How to flatten a List?
How can I easily flatten a List
in Dart?
For example:
var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var b = [1, 2, 3, 'a', 'b', 'c', true, false, true];
How do I turn a
into b
, i.e. into a single List
containing all those values?
Solution 1:
The easiest way I know of is to use Iterable.expand()
with an identity function. expand()
takes each element of an Iterable, performs a function on it that returns an iterable (the "expand" part), and then concatenates the results. In other languages it may be known as flatMap.
So by using an identity function, expand will just concatenate the items. If you really want a List, then use toList()
.
var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var flat = a.expand((i) => i).toList();
Solution 2:
I don't think there's a built-in method for that, but you can always reduce it to a single value:
var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var flatten = a.reduce([], (p, e) {
p.addAll(e);
return p;
});
print(flatten);
I wish addAll()
would return the original list. Currently it returns nothing. If that were true, you could write a single liner: a.reduce([], (p, e) => p.addAll(e))
.
Alternatively, you can just loop through the list and add:
var flatten = [];
a.forEach((e) => flatten.addAll(e));
Solution 3:
With Dart 2.3 or later, you instead can use collection-for
and the spread operator to easily flatten a list. I personally find it to be more readable than using Iterable.expand
:
List<T> flatten<T>(Iterable<Iterable<T>> list) =>
[for (var sublist in list) ...sublist];
var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var b = flatten(a);
print(b); // Prints: [1, 2, 3, a, b, c, true, false, true]
If there are nested lists that you need to recursively flatten, you could use:
List<T> flattenDeep<T>(Iterable<dynamic> list) => [
for (var element in list)
if (element is! Iterable) element else ...flattenDeep(element),
];
var a = [[1, [[2], 3]], [[['a']], 'b', 'c'], [true, false, [true]]];
var b = flattenDeep(a);
print(b) // Prints: [1, 2, 3, a, b, c, true, false, true]