Is there any way I can separate a List<SomeObject>
into several separate lists of SomeObject
, using the item index as the delimiter of each split?
Let me exemplify:
I have a List<SomeObject>
and I need a List<List<SomeObject>>
or List<SomeObject>[]
, so that each of these resulting lists will contain a group of 3 items of the original list (sequentially).
eg.:
Original List:
[a, g, e, w, p, s, q, f, x, y, i, m, c]
Resulting lists:
[a, g, e], [w, p, s], [q, f, x], [y, i, m], [c]
I'd also need the resulting lists size to be a parameter of this function.
If the list is of type system.collections.generic you can use the "CopyTo" method available to copy elements of your array to other sub arrays. You specify the start element and number of elements to copy.
You could also make 3 clones of your original list and use the "RemoveRange" on each list to shrink the list to the size you want.
Or just create a helper method to do it for you.
This is an old question but this is what I ended up with; it enumerates the enumerable only once, but does create lists for each of the partitions. It doesn't suffer from unexpected behavior when
ToArray()
is called as some of the implementations do:I took the primary answer and made it to be an IOC container to determine where to split. (For who is really looking to only split on 3 items, in reading this post while searching for an answer?)
This method allows one to split on any type of item as needed.
So for the OP the code would be
Ok, here's my take on it:
Example Usage
Explanations
The code works by nesting two
yield
based iterators.The outer iterator must keep track of how many elements have been effectively consumed by the inner (chunk) iterator. This is done by closing over
remaining
withinnerMoveNext()
. Unconsumed elements of a chunk are discarded before the next chunk is yielded by the outer iterator. This is necessary because otherwise you get inconsistent results, when the inner enumerables are not (completely) consumed (e.g.c3.Count()
would return 6).Just putting in my two cents. If you wanted to "bucket" the list (visualize left to right), you could do the following:
Try the following code.
The idea is to first group the elements by indexes. Dividing by three has the effect of grouping them into groups of 3. Then convert each group to a list and the
IEnumerable
ofList
to aList
ofList
s