Question
In VB.Net, If I have a collection like this:
Dim collection As IEnumerable(Of Integer) = Enumerable.Range(0, 99)
How I could split it in groups/Ienumerables of an indeterminated amount of elements?
Conditions
Using a LINQ query (not MORELinq or any other 3rd party libs)
Not writting a Function
, just using (or appending to the collection) a LINQ query avoiding the insertion of a custom and generic procedure to split in parts.
Not generating an Anonymous
Type (because I will respect the VB.Net Option
Statements).
Research
I've read at these questions but I was not able to properly translate the C# LINQ querys into VB.Net (even online translators fails and need much modifications):
Split a collection into `n` parts with LINQ?
How can I split an IEnumerable<String> into groups of IEnumerable<string>
Split List into Sublists with LINQ
Split a entity collection into n parts
These are two different approaches that I've tried to adapt from the solutions given in those S.O. questions above, but my translations doesn't works, the first can't compile because the condition of Group By and the second does not generates an splitted collection, it generates a collection per each element:
1.
Dim parts As Integer = 4
Dim i As Integer = 0
Dim splits As IEnumerable(Of IEnumerable(Of Integer)) =
From item As Integer In collection
Group By (Math.Max(Interlocked.Increment(i), i - 1) Mod parts)
Into Group
Select Group.AsEnumerable
2.
Dim parts As Integer = 4
Dim result As IEnumerable(Of IEnumerable(Of Integer)) =
collection.Select(Function(s, i) New With
{
Key .Value = s,
Key .Index = i
}
).GroupBy(Function(item)
Return (item.Index >= (item.Index / parts)) And (item.Index >= item.Value)
End Function,
Function(item) item.Value).Cast(Of IEnumerable(Of Integer))()
Expected Results
So, If I have a source collection like this:
Dim collection As IEnumerable(Of Integer) = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
And supposing that I have that imaginary LINQ query that can split into a variable named splits
by the value specified on variable parts
:
Dim parts as Integer = ...
Dim splits As IEnumerable(Of IEnumerable(Of Integer)) =
From value As Integer In collection (Linq Query that splits by given 'parts' value)
If I choosen that parts
value is 4 then the result will be an IEnumerable(Of IEnumerable(Of Integer))
which will contains 3 collections, where:
splits(0) = {1, 2, 3, 4}
splits(1) = {5, 6, 7, 8}
splits(2) = {9, 10}
If I choosen that parts
value is 5 then the result will be an IEnumerable(Of IEnumerable(Of Integer))
which will contains 2 collections, where:
splits(0) = {1, 2, 3, 4, 5}
splits(1) = {6, 7, 8, 9, 10}
If I choosen that parts
value is 1 then the result will be an IEnumerable(Of IEnumerable(Of Integer))
which will contains the identical source collection because I choosen to split in just 1 part:
splits(0) = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
If I choosen that parts
value is 10 then the result will be an IEnumerable(Of IEnumerable(Of Integer))
which will contains 10 collections, one collection per each value of the source example collection:
splits(0) = {1}
splits(1) = {2}
splits(2) = {3}
and so on...