How do I split or chunk a list into equal parts, with Dart?
20,752
Solution 1
Here is another way:
var chunks = [];
int chunkSize = 2;
for (var i = 0; i < letters.length; i += chunkSize) {
chunks.add(letters.sublist(i, i+chunkSize > letters.length ? letters.length : i + chunkSize));
}
return chunks;
Run it on dartpad
Solution 2
Quiver (version >= 0.18) supplies partition()
as part of its iterables library (import 'package:quiver/iterables.dart'). The implementation returns lazily-computed Iterable
, making it pretty efficient. Use as:
var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
var pairs = partition(letters, 2);
The returned pairs
will be an Iterable<List>
that looks like:
[['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']]
Solution 3
A slight improvement on Seth's answer to make it work with any list or chunk size:
var len = letters.length;
var size = 2;
var chunks = [];
for(var i = 0; i< len; i+= size)
{
var end = (i+size<len)?i+size:len;
chunks.add(letters.sublist(i,end));
}
Solution 4
pairs(list) => list.isEmpty ? list : ([list.take(2)]..addAll(pairs(list.skip(2))));
Solution 5
another solution;
List chunk(List list, int chunkSize) {
List chunks = [];
int len = list.length;
for (var i = 0; i < len; i += chunkSize) {
int size = i+chunkSize;
chunks.add(list.sublist(i, size > len ? len : size));
}
return chunks;
}
List nums = [1,2,3,4,5];
print(chunk(nums, 2));
// [[1,2], [3,4], [5]]
Comments
-
Seth Ladd over 2 years
Assume I have a list like:
var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
I would like a list of lists of 2 elements each:
var chunks = [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']];
What's a good way to do this with Dart?
-
Seth Ladd about 10 yearsIs there a better way?
-
Alan Knight about 10 yearsFor efficiency I suspect the boring for loop with an index is the best, but it's fun to try and be terse.
-
Florian Loitsch about 10 yearsThis solution is in O(n^2). I like terse code, but I'm not sure it's worth the performance hit.
-
Rusty Rob about 10 yearsOne thing I like about python is the zip function which allows you to go pairs_iter = zip(it, it)
-
Rusty Rob about 10 yearsdart could probably do with a zip function. columns = zip(rows) or rows = zip(columns) is fairly common.
-
Rusty Rob about 10 yearsalso the general case would be zip(repeat(it, n)) to get chunks of length n.
-
cbracken about 10 years
-
Hasan A Yousef about 6 yearswhat is the
~
-
Günter Zöchbauer about 6 yearsIt's for integer division
~/ | Divide, returning an integer result
dartlang.org/guides/language/language-tour -
Pom12 almost 4 yearsThis answer does not work when the list does not contain a pair number of elements. You should add a check of whether you reached the end before calling sublist, otherwise you will get an error like
RangeError (end): Invalid value: Not in range 14..15, inclusive: 16
-
Galeen almost 4 yearschunks.add(letters.sublist(i, i+2 > letters.length ? letters.length : i + 2));
-
Suragch over 2 yearsOops, I missed that Seth Ladd's answer already used
sublist
. I'll keep this as a more generalized example, though. -
Jebiel over 2 yearsWhat about using ListComprehension? [for (int i = 0; i < list.length; i += chunkSize) list.sublist(i, min(i + chunkSize, list.length))] By using min(), you don't need to do any ternary check, and you are sure to get the remaining elements as a sublist, even though there are not enough to satisfy chunkSize. The result of above listComprehension looks very much like the result of quiver's partition function, as described by @cbracken.
-
genericUser over 2 years@Pom12 I have edited the answer to support different sizes of chunks and added a dartpad link. Enjoy!