This tutorial shows you how to find the difference of elements between two `List`s in Dart.

If you have two `List`s and you want to find what elements are present in a `List` but not in the other one, you can read the examples in this tutorial. Below are the `List`s that we are going to find the difference.

``````  final l1 = ['grass', 'water', 'fire', 'grass'];
final l2 = ['water', 'fire', 'dragon', 'fairy'];``````

In this tutorial, we are going to find the elements in `l1` that are not in `l2` and the other way around. The expected output is:

• Elements in `l1` not in `l2`: `['grass', 'grass']`
• Elements in `l2` not in `l1`: `['dragon', 'fairy'] `

## Using Loop

Since a `List` is an `Iterable`, you can use a for loop to iterate the elements. Then, check whether the element exists in the other `List`. If it doesn't exist, the element should be included in the result.

``````  List<T> differenceWithLoop<T>(List<T> a, List<T> b) {
final List<T> result = [];

for (T element in a) {
if (!b.contains(element)) {
}
}

return result;
}

print(differenceWithLoop(l1, l2));
print(differenceWithLoop(l2, l1));``````

Output:

``````  [grass, grass]
[dragon, fairy]``````

## Using `where`

Dart's `Iterable` has a `where` operator which is used to create an `Iterable` whose elements match the passed predicate function. For this case, we can create a predicate function that returns `true` if the element doesn't exist in the other `List`.

``````  List<T> differenceWithWhere<T>(List<T> a, List<T> b) {
return a.where((element) => !b.contains(element)).toList();
}

print(differenceWithLoop(l1, l2));
print(differenceWithLoop(l2, l1));``````

Output:

``````  [grass, grass]
[dragon, fairy]``````

## Using `Set.difference`

Another idea is by converting the `List`s to `Set`s. `Set` has a method named `difference` which returns a new `Set` with the elements of the current `Set` that are not in the other `Set` passed as the argument. A `List` can be converted to a `Set` by using `toSet` method. Because converted to a `Set`, the duplicate elements can only appear at most once in the result.

``````  List<T> differenceWithSet<T>(List<T> a, List<T> b) {
return a.toSet().difference(b.toSet()).toList();
}

print(differenceWithLoop(l1, l2));
print(differenceWithLoop(l2, l1));``````

Output:

``````  [grass]
[dragon, fairy]``````

## Find Difference Between Lists of Mutable Objects

If the elements contain mutable objects, you may need to understand how object comparison works. The `Iterable.contains` and `Set.difference` use the equality operator to compare the elements.

For example, there is a class named `Item` with two fields as shown below.

``````  class Item {
String name;
double price;

Item({
required this.name,
required this.price,
});
}``````

Then, we create two `List`s of `Item` instances and try to find the difference using any of the methods above.

``````  final Item item1a = Item(name: 'A', price: 100);
final Item item1b = Item(name: 'B', price: 200);
List<Item> items = [item1a, item1b];

final Item item2a = Item(name: 'A', price: 100);
final Item item2b = Item(name: 'B', price: 200);
List<Item> items2 = [item2a, item2b];

print(differenceWithLoop(items, items2));``````

Output

``  [(name: A, price: 100.0), (name: B, price: 200.0), (name: C, price: 300.0)] // all items are considered different``

From the output, we can see that all instances in the first `List` are considered not found in the second `List`, even though the first two instances of the first `List` have the corresponding instance in the second `List` with the same values for all fields. That's because the equality operator compares the objects based on the memory reference by default. You can read the details in our tutorial about object comparison in Dart.

If you want to make the objects compared by the values of the fields, a possible solution is by overriding the equality operator. If you do that, you also have to override the `hashCode` property.

``````  class Item {
String name;
double price;

Item({
required this.name,
required this.price,
});

@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}

return (other is Item
&& other.runtimeType == runtimeType
&& other.name == name
&& other.price == price
);
}

@override
int get hashCode => Object.hash(name.hashCode, price.hashCode);
}``````

After overriding the equality operator, the result will be different since two `Item` instances with the same `name` and `price` are considered equal. Another alternative is canonicalizing the instances by using const constructor.

Output

``  [(name: C, price: 300.0)]// only the third item is considered different``

## Summary

There are several ways to get the difference between two `List`s in Dart. You can iterate using for loop or filter using `where` to find the elements that are not in the other `List`. Another way is converting the `List`s to `Set` and use the `difference` method. If the `List` contains mutable objects, you may consider overriding the equality operator if necessary.