如何使用Dart将列表拆分或分块为相等的部分?

Set*_*add 11 dart

假设我有一个列表,如:

var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
Run Code Online (Sandbox Code Playgroud)

我想列出每个包含2个元素的列表:

var chunks = [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']];
Run Code Online (Sandbox Code Playgroud)

用Dart做这件事的好方法是什么?

The*_*xyQ 35

Dart官方的collection包有slices扩展方法,使用方法如下:

final letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
final chunks = letters.slices(2); // [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']]
Run Code Online (Sandbox Code Playgroud)


Eri*_* K. 16

Seth 的答案略有改进,使其适用于任何列表或块大小:

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));
}
Run Code Online (Sandbox Code Playgroud)


Ala*_*ght 11

  pairs(list) => list.isEmpty ? list : ([list.take(2)]..addAll(pairs(list.skip(2))));
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案是O(n ^ 2).我喜欢简洁的代码,但我不确定它的性能是否值得. (4认同)
  • 为了效率,我怀疑带有索引的无聊 for 循环是最好的,但是尝试简洁是很有趣的。 (2认同)

cbr*_*ken 10

Quiver(版本> = 0.18)partition()作为其iterables库(import'package:quiver/iterables.dart')的一部分提供.实现返回延迟计算Iterable,使其非常有效.用于:

var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
var pairs = partition(letters, 2);
Run Code Online (Sandbox Code Playgroud)

返回的pairs内容Iterable<List>如下:

[['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']]
Run Code Online (Sandbox Code Playgroud)


Set*_*add 8

这是另一种方式:

  var chunks = [];
  for (var i = 0; i < letters.length; i += 2) {
    chunks.add(letters.sublist(i, i+2));
  }
  return chunks;
Run Code Online (Sandbox Code Playgroud)

  • 当列表不包含一对元素时,这个答案不起作用。您应该在调用 sublist 之前添加检查是否到达末尾,否则您将收到类似“RangeError (end): Invalid value: Not in range 14..15, Included: 16”的错误 (2认同)

小智 8

我找到了一个简单的解决方案:

var subList = mylist.take(3); // take 3 items first
var subList = mylist.skip(2).take(3); // take [2..5] items
Run Code Online (Sandbox Code Playgroud)


Ahm*_*şek 7

另一种解决方案;

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]]
Run Code Online (Sandbox Code Playgroud)


Set*_*add 5

这是一种方法:

letters.fold([[]], (list, x) {    
  return list.last.length == 2 ? (list..add([x])) : (list..last.add(x));
});
Run Code Online (Sandbox Code Playgroud)


Aut*_*rab 5

其他方式:

extension IterableExtensions<E> on Iterable<E> {
  Iterable<List<E>> chunked(int chunkSize) sync* {
    if (length <= 0) {
      yield [];
      return;
    }
    int skip = 0;
    while (skip < length) {
      final chunk = this.skip(skip).take(chunkSize);
      yield chunk.toList(growable: false);
      skip += chunkSize;
      if (chunk.length < chunkSize) return;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

测试:

void main() {
  test("list chunked", () {
    final emptyList = [];
    final letters = ['a', 'b', 'c', 'd', 'e', 'f'];
    final digits = List.generate(32, (index) => index);
    print(emptyList.chunked(2));
    print(letters.chunked(2));
    print(digits.chunked(2));

    print(emptyList.chunked(3));
    print(letters.chunked(3));
    print(digits.chunked(3));

    print(emptyList.chunked(5));
    print(letters.chunked(5));
    print(digits.chunked(5));
  });
}
Run Code Online (Sandbox Code Playgroud)

输出:

([])
([a, b], [c, d], [e, f])
([0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11], ..., [28, 29], [30, 31])
([])
([a, b, c], [d, e, f])
([0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], ..., [27, 28, 29], [30, 31])
([])
([a, b, c, d, e], [f])
([0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], ..., [25, 26, 27, 28, 29], [30, 31])
Run Code Online (Sandbox Code Playgroud)