Seth Ladd
Seth Ladd

Reputation: 120439

How do I compare two lists as being equal and containing the same objects, in Dart?

I have two lists:

List fruits = ['apples', 'bananas'];
List foods = ['apples', 'bananas'];

How can I compare fruits and foods and ensure that both lists have the same objects in the same order?

Upvotes: 8

Views: 6694

Answers (3)

Jitesh Mohite
Jitesh Mohite

Reputation: 34170

Flutter has foundation.dart class listEquals method which compare the list

import 'package:flutter/foundation.dart';

void main() {
  List fruits = ['apples', 'bananas'];
  List foods = ['apples', 'bananas'];
  print(listEquals(fruits, foods)); // true

}

Also, setEquals and mapEquals are there to compare map and set.

Upvotes: 2

Patrice Chalin
Patrice Chalin

Reputation: 16100

The recommended way to compare lists for equality (rather than identity) is by using the Equality classes from the following package

import 'package:collection/equality.dart';

E.g.,

Function eq = const ListEquality().equals;
print(eq(fruits, foods)); // => true

This works for your case because the fruits and foods contain corresponding arguments 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 deepEq = const DeepCollectionEquality.unordered().equals;

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

Upvotes: 7

Dennis Kaselow
Dennis Kaselow

Reputation: 4551

There are several ways to achieve this and this won't be a complete list for sure. But anyways:

Every solution I present, would require a length check beforehand fruits.length == foods.length, so I am leaving that out to keep it short.

The obvious solution would be to iterate over the length, but I guess, that's not what you want otherwise you wouldn't have asked this question:

var equals = true;
for (int i = 0; i < fruits.length; i++) {
  if (fruits[i] != foods[i]) {
    equals = false;
    break;
  }
}
print(equals);

Another solution could be to use fold:

var index = 0;
equals = fruits.fold(true, (result, item) => result && item == foods[index++]);
print(equals);

The downside of this approach is, that it would keep iterating even if there was a mismatch.

Another possibility would be using firstWhere

var index = 0;
equals = fruits.firstWhere((item) => item != foods[index++], orElse: () => null) == null;
print(equals);

The downside of this approach is the null check, because it may not be obvious that this is a check for equality, but it would stop iterating once the first mismatch is found.

Upvotes: 2

Related Questions