如何在 Flutter 中从列表创建子列表

How to make sublists from a list in Flutter

提问人:burbuja 提问时间:10/19/2023 最后编辑:burbuja 更新时间:10/19/2023 访问量:106

问:

我有一个数字列表,我想制作子列表, 其中每个子列表从 1 开始,到 3 结束。

这是我的清单:

List<String> items = [ '1', '2', '3', '1', '2', '4', '3', '1', '3' ];

这是我想要的:listOfLists = [[1,2,3], [1,2,4,3], [1,3]]

Flutter 列表 循环

评论

0赞 Randal Schwartz 10/19/2023
这是一个不完整的规范。如果第一项不是 1 怎么办?如果没有 3 个来结束一个细分怎么办?

答:

1赞 Ada 10/19/2023 #1

您可以像这样遍历您的列表:

void main() {
  List<String> items = ['1', '2', '3', '1', '2', '4', '3', '1', '3'];
  List<List<String>> listOfLists = [];

  int? startIndex;
  int? endIndex;

  for (int i = 0; i < items.length; i++) {
    final item = items[i];

    if (item == '1') {
      if (startIndex != null && endIndex != null) {
        listOfLists.add(items.sublist(startIndex, endIndex + 1));
      }
      startIndex = i;
      endIndex = null;
    } else if (item == '3') {
      endIndex = i;
    }
  }

  // Add the last sublist if it ends with '3'
  if (startIndex != null && endIndex != null) {
    listOfLists.add(items.sublist(startIndex, endIndex + 1));
  }

  print(listOfLists);
}

初始化以存储子列表。 循环访问原始列表项: 遇到“1”时,将 设置为当前索引。 遇到“3”时,将 设置为当前索引。 如果在找到“3”之前再次找到“1”,则表示新的子列表已启动,因此将上一个子列表添加到 。 最后,如果最后一个子列表以“3”结尾,则添加它。listOfListsstartIndexendIndexlistOfLists

3赞 Ivo 10/19/2023 #2

一种单行的方法是

listOfLists = items.join().split(RegExp(r'(?<=3)(?=1)')).map((e) => e.split('')).toList();

编辑:

我在第一个答案之后才知道。这将使它更加简洁:splitBetween

listOfLists = items.splitBetween((first, second) => first == '3' && second == '1').toList();

这确实需要包,因此您还需要这样做collection

import 'package:collection/collection.dart';

评论

1赞 pskink 10/19/2023
顺便说一句,还有 和方法(在某些情况下也很方便)splitBeforesplitAfter
1赞 Randal Schwartz 10/19/2023 #3

我根据猜测添加了几个测试:

void main(List<String> arguments) {
  final items = ['1', '2', '3', '1', '2', '4', '3', '1', '3'];
  var accum = <String>[];
  final result = <List<String>>[];
  for (final item in items) {
    print(item);
    switch (item) {
      case '1':
        if (accum.isNotEmpty) {
          throw Exception('accum is not empty $accum but saw 1');
        }
        accum.add(item);

      case '3':
        if (accum.isEmpty) {
          throw Exception('accum is empty but saw 3');
        }
        accum.add(item);
        result.add(accum);
        accum = [];
      default:
        if (accum.isEmpty) {
          throw Exception('accum is empty but saw $item, not 1');
        }
        accum.add(item);
    }
  }
  if (accum.isNotEmpty) {
    throw Exception('accum is not empty but saw $accum');
  }
  print(result);
}

评论

0赞 pskink 10/19/2023
splitBetween来救援!如果第一项为 1,最后一项为 3,则只应添加两个测试:final input = ['1','2','3','1','2','4','3','1','3']; /* needs: import 'package:collection/collection.dart'; */ final output = input.splitBetween((first, second) => first == '3' && second == '1').toList(); print('$input => $output');
0赞 Randal Schwartz 10/19/2023
如果列表像我的代码那样组织不当,则不会报告错误。
0赞 pskink 10/19/2023
所以测试回调需要扩展一点......(3,1) 正常 (3,?) 错误 (?,1) 错误 -splitBetween
0赞 Randal Schwartz 10/19/2023
这不包括第一项不是 1 或最后一项不是 3 的情况,除非 splitBetween 也在边缘作为空操作调用,但仅用于验证。
0赞 pskink 10/20/2023
是的,它会:并称之为bool test(int i, String first, String second) => switch ((first, second)) { ('3', '1') => true, ('3', _) || (_, '1') => throw 'error at position $i: ($first, $second)', (_, _) => false, };input.splitBetweenIndexed(test);
-1赞 Dhruvil 10/19/2023 #4

您还可以使用 sublist() 方法创建整个列表的子列表,从某个索引开始:

列表编号 = [1, 2, 3, 4, 5]; 列表子列表 = numbers.sublist(2);

print(子列表);[3, 4, 5]