Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partitioning a list given total partitions and partition number

Tags:

c#

linq

.net-3.5

Suppose I'm given a list of items:

[ A, B, C, D, E, F, G, H, I, J ]

I'm asked to split these into 3 lists, and take the second list:

[ A, B, C, D ] [ E, F, G ] [ H, I, J ]

How would I do this?

I'm thinking the function would look like

public List<Item> SplitItems(
    List<Item> items, 
    int totalPartitions, 
    int partitionNumber) { }

I'm able to get the list if the partitionNumber is 1 (the first set) using calculations involving the modulo operation of the totalPartitions and the partitionNumber, but I'm having issues getting the list of partitionNumber 2 and above.


@Blorgbeard: Here's the code that I have so far. Again, I'm only able to handle the first partition:

int itemsCount = items.Count;
int setCount = itemsCount/totalPartitions + ((itemsCount%totalPartitions >= partitionNumber) ? 1 : 0);
return webItems.Take(setCount).ToList();
like image 365
Katie Avatar asked Dec 11 '25 10:12

Katie


2 Answers

int smallPartitionSize = list.Count / totalPartitions;
int remainder = list.Count % totalPartitions;
int selectedPartitionSize = smallPartitionSize + (partitionNumber <= remainder) ? 1 : 0;
var start = (partitionNumber - 1) * smallPartitionSize + Math.Min(remainder, partitionNumber - 1);
return list.Skip(start).Take(selectedPartitionSize);
like image 104
Dave Mackersie Avatar answered Dec 12 '25 22:12

Dave Mackersie


Another approach is to create a collection of evenly distributed numbers 0-2 and Zip it with your items:

var items = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
var n = items.Length;

var partitioner = Enumerable.Range(0, n).Select (e => (e * 3) / n );
// Values: { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2 }

var result = partitioner.Zip(items, (i,s) => new {i,s})
                        .Where(z => z.i == 1).Select(z => z.s).ToList();
like image 28
Gert Arnold Avatar answered Dec 12 '25 22:12

Gert Arnold



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!