How can I compare Lists for equality in Dart?

I'm comparing two lists in Dart like this:

main() {
    if ([1,2,3] == [1,2,3]) {
        print("Equal");
    } else {
        print("Not equal");
    }   
}

But they are never equal. There doesn't seem to be an equal() method in the Dart API to compare Lists or Collections. Is there a proper way to do this?


Solution 1:

To complete Gunter's answer: the recommended way to compare lists for equality (rather than identity) is by using the Equality classes from the following package

import 'package:collection/collection.dart';

Edit: prior to 1.13, it was import 'package:collection/equality.dart';

E.g.:

Function eq = const ListEquality().equals;
print(eq([1,'two',3], [1,'two',3])); // => true

The above prints true because the corresponding list elements that are identical(). If you want to (deeply) compare lists that might contain other collections then instead use:

Function deepEq = const DeepCollectionEquality().equals;
List list1 = [1, ['a',[]], 3];
List list2 = [1, ['a',[]], 3];
print(    eq(list1, list2)); // => false
print(deepEq(list1, list2)); // => true

There are other Equality classes that can be combined in many ways, including equality for Maps. You can even perform an unordered (deep) comparison of collections:

Function unOrdDeepEq = const DeepCollectionEquality.unordered().equals;
List list3 = [3, [[],'a'], 1];
print(unOrdDeepEq(list2, list3)); // => true

For details see the package API documentation. As usual, to use such a package you must list it in your pubspec.yaml:

dependencies:
  collection: any

Solution 2:

For those using Flutter, it has the native function listEquals, which compares for deep equality.

import 'package:flutter/foundation.dart';

var list1 = <int>[1, 2, 3];
var list2 = <int>[1, 2, 3];

assert(listEquals(list1, list2) == true);
import 'package:flutter/foundation.dart';

var list1 = <int>[1, 2, 3];
var list2 = <int>[3, 2, 1];

assert(listEquals(list1, list2) == false);

Note that, according to the documentation:

The term "deep" above refers to the first level of equality: if the elements are maps, lists, sets, or other collections/composite objects, then the values of those elements are not compared element by element unless their equality operators (Object.operator==) do so.

Therefore, if you're looking for limitless-level equality, check out DeepCollectionEquality, as suggested by Patrice Chalin.

Also, there's setEquals and mapEquals if you need such feature for different collections.