次のようなリストがあるとします。
var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
それぞれ2つの要素のリストのリストが欲しい:
var chunks = [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']];
Dartでこれを行う良い方法は何ですか?
1 つの方法を次に示します。
letters.fold([[]], (list, x) {
return list.last.length == 2 ? (list..add([x])) : (list..last.add(x));
});
この方法は、長さが奇数のリストで機能します。
var nums = [1, 2, 3, 4, 5];
var pairs = new List.generate(nums.length~/2, (i) => [nums[2 * i], nums[2 * i + 1]]);
リストの長さが偶数でない場合は、おそらくエラーをスローしたり、フィラー値を提供したりすることができます。
別の解決策;
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]]
ペアのイテラブルを作成し、リストとして本当に必要な場合は .toList を使用することをお勧めします。このソリューションは、リストだけでなく、任意のイテラブルにも適用できます。まず、リスト (偶数長) でのみ機能する単純なソリューション (Robert King から提供されたソリューションのように):
new Iterable.generate(letters.length ~/ 2,
(i) => [letters[2*i], letters[2*i + 1]])
より一般的な解決策は複雑です。
class mappedIterable extends Object implements Iterable with IterableMixin {
Function generator;
mappedIterable(Iterable source, Iterator this.generator(Iterator in));
Iterator get iterator => generator(source.iterator);
}
class Pairs implements Iterator {
Iterator _source;
List _current = null;
Pairs(Iterator this._source);
List get current => _current;
bool moveNext() {
bool result = _source.moveNext();
_current = [_source.current, (_source..moveNext()).current];
return result;
}
}
Iterable makePairs(Iterable source) =>
new mappedIterable(source, (sourceIterator) => new Pairs(sourceIterator));
print(makePairs(letters))
イテラブルからペアのイテラブルを作成するよりも、ストリームからペアのストリームを作成する方が実際には簡単なようです。