DartでList
を簡単にフラット化するにはどうすればよいですか?
例えば:
var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var b = [1, 2, 3, 'a', 'b', 'c', true, false, true];
a
をb
に、つまりこれらすべての値を含む単一のList
に変換するにはどうすればよいですか?
私が知っている最も簡単な方法は、恒等関数でIterable.expand()
を使用することです。 expand()
は、Iterableの各要素を受け取り、Iterable( "expand"部分)を返す関数を実行して、結果を連結します。他の言語では、flatMapとして知られている場合があります。
したがって、ID関数を使用することにより、expandはアイテムを連結するだけです。本当にリストが必要な場合は、toList()
を使用してください。
var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var flat = a.expand((i) => i).toList();
そのための組み込みの方法はないと思いますが、いつでも単一の値に減らすことができます。
_var a = [[1, 2, 3], ['a', 'b', 'c'], [true, false, true]];
var flatten = a.reduce([], (p, e) {
p.addAll(e);
return p;
});
print(flatten);
_
addAll()
が元のリストを返すことを望みます。現在、何も返しません。それが本当なら、あなたは単一のライナーを書くことができます:a.reduce([], (p, e) => p.addAll(e))
。
または、リストをループして追加することもできます。
_var flatten = [];
a.forEach((e) => flatten.addAll(e));
_
拡張メソッドを使用したソリューションは、このケースを満たすのに適しています。
expect(ListTools.getFlatList([[1],["hello",2],["test"]]),orderedEquals([1,"hello",2,"test"]));
しかし、これらのものではありません
expect(ListTools.getFlatList([[1],["hello",2,["foo",5]],["test"]]),orderedEquals([1,"hello",2,"foo",5,"test"]));
expect(ListTools.getFlatList([1,["hello",2],"test"]),orderedEquals([1,"hello",2,"test"]));
これらのテストケースを満たすには、次の関数のようなより再帰的なものが必要です。
List getFlatList(List list) {
List internalList = new List();
list.forEach((e) {
if (e is List) {
internalList.addAll(getFlatList(e));
} else {
internalList.add(e);
}
});
return internalList;
}
宜しくお願いします、
セバスチャン
これは、ジェネレーターを使用して効率的に行うことができます。
Iterable<T> flatten<T>(Iterable<Iterable<T>> items) sync* {
for (var i in items) {
yield* i;
}
}
Iterable<X> flatMap<T,X>(Iterable<Iterable<T>> items, X Function(T) f) =>
flatten(items).map(f);