Dart - find duplicate values on a List

Viewed 9650

how can I find duplicate values on a list, Let's say I got a List like this:

List<Map<String, dynamic>> users = [
    { "name": 'John', 'age': 18 },
    { "name": 'Jane', 'age': 21 },
    { "name": 'Mary', 'age': 23 },
    { "name": 'Mary', 'age': 27 },
  ];

How I can iterate the list to know if there are users with the same name?

4 Answers

A simple way would be this:

void main() {
  List<Map<String, dynamic>> users = [
    { "name": 'John', 'age': 18 },
    { "name": 'Jane', 'age': 21 },
    { "name": 'Mary', 'age': 23 },
    { "name": 'Mary', 'age': 27 },
  ];
  List names = List();
  users.forEach((u){
    if (names.contains(u["name"])) print("duplicate ${u["name"]}");
    else names.add(u["name"]);
  });
}

Result:

duplicate Mary

Probably a cleaner solution with extensions.

By declaring:

extension ListExtensions<E> on List<E> {
  List<E> removeAll(Iterable<E> allToRemove) {
    if (allToRemove == null) {
      return this;
    } else {
      allToRemove.forEach((element) {
        this.remove(element);
      });
      return this;
    }
  }

  List<E> getDupes() {
    List<E> dupes = List.from(this);
    dupes.removeAll(this.toSet().toList());
    return dupes;
  }
}

then you can find your duplicates by calling List.getDupes()

Note that the function removeAll doesn't exist in my current Dart library, in case you're reading this when they implement it somehow.

Also keep in mind the equals() function. In a List<String>, ["Rafa", "rafa"] doesn't contain duplicates.

If you indeed want to achieve this level of refinement, you'd have to apply a distinctBy function:

extension ListExtensions<E> on List<E> {
  List<E> removeAll(Iterable<E> allToRemove) {
    if (allToRemove == null) {
      return this;
    } else {
      allToRemove.forEach((element) {
        this.remove(element);
      });
      return this;
    }
  }

  List<E> distinctBy(predicate(E selector)) {
    HashSet set = HashSet();
    List<E> list = [];
    toList().forEach((e) {
      dynamic key = predicate(e);
      if (set.add(key)) {
        list.add(e);
      }
    });

    return list;
  }

  List<E> getDupes({E Function(E) distinctBy}) {
    List<E> dupes = List.from(this);
    if (distinctBy == null) {
      dupes.removeAll(this.toSet().toList());
    } else {
      dupes.removeAll(this.distinctBy(distinctBy).toSet().toList());
    }

    return dupes;
  }
}

I had a feeling Rafael's answer had code similar to Kotlin so I dug around and saw that these functions are part of the kt_dart library which basically gets the Kotlin standard library and ports it to Dart.

I come from a Kotlin background so I use this package often. If you use it, you can simply make the extension this much shorter:

extension KtListExtensions<T> on KtList<T> {
  KtList<T> get duplicates => toMutableList()..removeAll(toSet().toList());
}

just make sure to add kt_dart on your pubspec: kt_dart: ^0.8.0

Example

final list = ['apples', 'oranges', 'bananas', 'apples'].toImmutableList();
final duplicates = list.duplicates; // should be ['apples'] in the form of an ImmutableList<String>
void main() {

  List<String> country = [
    "Nepal", 
    "Nepal", 
    "USA",
    "Canada",
    "Canada",
    "China",
    "Russia",
];
List DupCountry = [];
country.forEach((dup){
if(DupCountry.contains(dup)){
print("Duplicate in List= ${dup}");
}
else{
  DupCountry.add(dup);
}
});

}
Related