skip to Main Content

I have a list of numbers and I want to make sublists,
where each sublist begins at 1 and ends at 3.

This is my list :

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

This is what I want to get : listOfLists = [[1,2,3], [1,2,4,3], [1,3]]

4

Answers


  1. You can iterate through your list like this:

    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);
    }
    

    You initialize listOfLists to store the sublists.
    Iterating through the original list items:
    When you encounter ‘1’, you set the startIndex to the current index.
    When you encounter ‘3’, you set the endIndex to the current index.
    If you find ‘1’ again before finding ‘3’, it means a new sublist has started, so you add the previous sublist to listOfLists.
    In the end you add the last sublist if it ends with ‘3’.

    Login or Signup to reply.
  2. A oneliner way to do it is

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

    EDIT:

    I learned about splitBetween after my first answer. This will make it even more concise:

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

    This does require the collection package so you also need to do

    import 'package:collection/collection.dart';
    
    Login or Signup to reply.
  3. I added a couple of tests based on guesses:

    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);
    }
    
    Login or Signup to reply.
  4. You can also use the sublist() method to create a sublist of the entire list, starting at a certain index:

    List numbers = [1, 2, 3, 4, 5];
    List sublist = numbers.sublist(2);

    print(sublist); // [3, 4, 5]

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search