Trying to write a method that splits a list into sublists.
Private Function SplitIdsIntoChunks(ByVal keys As List(Of String)) As List(Of List(Of String))
Return keys _
.Select(Function(x, i) New With {Key .Index = i, Key .Value = x}) _
.GroupBy(Function(x) (x.Index / 10000)) _
.Select(Function(x) x.Select(Function(v) v.Value).ToList()) _
.ToList()
End Function
I used C# solution from here. C# solution works fine.
My version written in VB returns a collection of lists with one element instead of 10000. Where did I go wrong?
Thanks in advance.
Edit 1:
Usage:
Dim chunks As List(Of List(Of String)) = SplitIdsIntoChunks(keys)
'Keys' content:
My method returns a lists of lists with one item inside:
Expected result: list of two lists - 10000 items in first and 6256 in second.
The main 'problem' is that in c# dividing an int by an int, x.Index / 3
, results in an integer. Standard division /
in VB always results in a Double
and therefore a unique Group for each item. e.g.: {.33, .333333, .333334} etc.
The 'trick' is to use integer division \
to get an integer result. I also added a chunksize
argument to make it more flexible and reusable:
Private Function SplitIntoChunks(keys As List(Of String), chunkSize As Integer) As List(Of List(Of String))
Return keys.
Select(Function(x, i) New With {Key .Index = i, Key .Value = x}).
GroupBy(Function(x) (x.Index \ chunkSize)).
Select(Function(x) x.Select(Function(v) v.Value).ToList()).
ToList()
End Function
One other difference is that c#
is very flexible regarding line continuation, so the dot can be at the start or end of a line. VB (since VS2010) supports implicit line continuation after a great many things including member qualifier character (the dot .
) so you can get rid of the explicit line continuation (" _"
).
Usage:
' split list of 1000 into 300 chunks
Dim splits = SplitIntoChunks(myList, 300)
For n As Integer = 0 To splits.Count - 1
Console.WriteLine("Split {0} has {1} items", n.ToString(), splits(n).Count)
Next
Output/Result:
Split 0 has 300 items
Split 1 has 300 items
Split 2 has 300 items
Splits 3 has 100 items
Note that there is a lot of commentary on the linked C# post about performance of various methods. This just gets it working, some of the alternatives might perform better depending on what is actually being split. The Skip
and Take
approach used here is interesting too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With