How to delete duplicates in a dart List? list.distinct()?

后端 未结 11 2048
夕颜
夕颜 2020-12-01 05:21

How do i delete duplicates from a list without fooling around with a set? Is there something like list.distinct()? or list.unique()?

void main() {
  print(\"         


        
相关标签:
11条回答
  • 2020-12-01 05:23

    I have a library called Reactive-Dart that contains many composable operators for terminating and non-terminating sequences. For your scenario it would look something like this:

    final newList = [];
    Observable
       .fromList(['abc', 'abc', 'def'])
       .distinct()
       .observe((next) => newList.add(next), () => print(newList));
    

    Yielding:

    [abc, def]
    

    I should add that there are other libraries out there with similar features. Check around on github and I'm sure you'll find something suitable.

    0 讨论(0)
  • 2020-12-01 05:23

    Here it is working solution:

    var sampleList = ['1', '2', '3', '3', '4', '4'];
    //print('orignal: $sampleList');
    sampleList = Set.of(sampleList).toList();
    //print('processed: $sampleList');
    

    Output:

    orignal: [1, 2, 3, 3, 4, 4]
    processed: [1, 2, 3, 4]
    
    0 讨论(0)
  • 2020-12-01 05:29

    I didn't find any of the provided answers very helpful. Here is what I generally do:

        final ids = myList.map((e) => e.id).toSet();
        myList.retainWhere((x) => ids.remove(x.id));
    

    Of course you can use any attribute which uniquely identifies your objects, it doesn't have to be an id field.

    This approach is particularly useful for richer objects. For simple primitive types some of the answers already posted here are fine. Another nice side-effect of this solution is that unlike others provided here, this solution does not change the order of your original items in the list as it modifies the list in place!

    0 讨论(0)
  • 2020-12-01 05:30

    As for me one of best practices is sort array, then deduplicate it. Idea is stolen from low level languages. So,

    first make sort by your own, then deduplicate equal values that are going after each other.

    // easy example
    void dedup<T>(List<T> list, {removeLast: true}) {
      int shift = removeLast ? 1 : 0;
      T compareItem;
      for (int i = list.length - 1; i >= 0; i--) {
        if (compareItem == (compareItem = list[i])) {
          list.removeAt(i + shift);
        }
      }
    }
    
    // harder example
    void dedupBy<T, I>(List<T> list, I Function(T) compare, {removeLast: true}) {
      int shift = removeLast ? 1 : 0;
      I compareItem;
      for (int i = list.length - 1; i >= 0; i--) {
        if (compareItem == (compareItem = compare(list[i]))) {
          list.removeAt(i + shift);
        }
      }
    }
    
    
    void main() {
      List<List<int>> list = [[1], [1], [2, 1], [2, 2]];
      print('$list');
      dedupBy(list, (innerList) => innerList[0]);
      print('$list');
    
      print('\n removeLast: false');
    
      List<List<int>> list2 = [[1], [1], [2, 1], [2, 2]];
      print('$list2');
      dedupBy(list2, (innerList) => innerList[0], removeLast: false);
      print('$list2');
    }
    

    Output:

    [[1], [1], [2, 1], [2, 2]]
    [[1], [2, 1]]
    
    removeLast: false
    [[1], [1], [2, 1], [2, 2]]
    [[1], [2, 2]]
    
    0 讨论(0)
  • 2020-12-01 05:30

    this is other way...

    final reducedList = [];
    
    list.reduce((value, element) {
        if (value != element) reducedList.add(value);
        return element;
    });
    
    reducedList.add(list.last);
    
    print(reducedList);
    
    0 讨论(0)
  • 2020-12-01 05:31

    If you want to keep ordering or are dealing with more complex objects than primitive types. Store seen ids to the Set and filter away those ones that are already in the set.

    final list = ['a', 'a', 'b'];
    final seen = Set<String>();
    final unique = list.where((str) => seen.add(str)).toList();
    
    print(unique); // => ['a', 'b']
    
    
    0 讨论(0)
提交回复
热议问题