Reputation: 3298
I have two lists [1,2,3,4,5,6,7]
and [3,5,6,7,9,10]
. I want to get the difference of the first list and the second list.
The expected output would be [1,2,4]
since those are the only elements in only list 1 and not list 2.
I'm using Flutter and Dart. I looked this up on the internet, I know it seems like a simple question but I couldn't find anything.
Should be irrelevant but I'm using publishing for iOS
I'd prefer an answer without just a foreach loop, im looking to see if there is a library for it.
Upvotes: 24
Views: 26168
Reputation: 609
Some people may be searching for the symmetric difference rather than strict difference provided in the standard library. Here is an extension to Set which adds a symmetricDifference
function:
extension on Set {
/// Creates a set that is the _symmetric difference_ of this set and
/// another set. That is the set of all elements that are in this
/// set _or_ the other set, but not in _both_ sets.
Set<E> symmetricDifference<E>(Set<E> other) =>
difference(other).union(other.difference(this)) as Set<E>;
}
void main() {
final Set l = {1, 2, 3};
final Set r = {2, 3, 4};
assert(l.difference(r) == {1});
assert(r.difference(l) == {4});
assert(l.symmetricDifference(r) == {1, 4});
}
Upvotes: 0
Reputation: 1365
Because list.contains()
is an O(n)
operation, other answers have terrible performance and don't consider duplicate elements in the lists.
Myers diff algorithm can help if you want to diff two lists.
Here is the dart implementation by @knaeckeKami.
https://github.com/knaeckeKami/diffutil.dart
Upvotes: 0
Reputation: 31
void main() {
var listA = [1,2,3,4,5,6,7];
var listB = [3,5,6,7,9,10];
listB.map((e)=>listA.remove(e)).toList();
print(listA);
}
Upvotes: 0
Reputation: 2033
Use the !.contains
for nullable variable.
var a = [1,2,3,4,5,6,7];
var b = [3,5,6,7,9,10];
a.removeWhere((element) => b!.contains(element));
Upvotes: 0
Reputation: 2424
Simple & Recommended Way to do this is
var a = [1,2,3,4,5];
var b = [1,2];
a.removeWhere((element) => b.contains(element));
print(a); //[3, 4, 5]
Upvotes: 6
Reputation: 2042
if you need single line , just do like this one
print([1,2,3,4,5,6,7].where((e) => ![3,5,6,7,9,10].contains(e)).toList());
result is
[1, 2, 4]
Upvotes: 4
Reputation: 1057
Since you will be looking for unique elements you could use the difference method of the Set class (https://api.flutter.dev/flutter/dart-core/Set/difference.html) to do something like this:
List<int> first = [1,2,3,4,5,6,7];
List<int> second = [3,5,6,7,9,10];
List<int> difference = first.toSet().difference(second.toSet()).toList();
print(difference.toString());
// prints [1, 2, 4]
Upvotes: 33
Reputation: 2593
This seems to do the trick:
void main() {
final l1 = [1, 2, 3];
final l2 = [3, 4, 5];
print(listDiff(l1, l2)); // [1, 2, 4, 5]
}
List<T> listDiff<T>(List<T> l1, List<T> l2) => (l1.toSet()..addAll(l2))
.where((i) => !l1.contains(i) || !l2.contains(i))
.toList();
Upvotes: 2
Reputation: 1421
you can do something like this:
List<double> first = [1,2,3,4,5,6,7];
List<double> second = [3,5,6,7,9,10];
List<double> output = [];
first.forEach((element) {
if(!second.contains(element)){
output.add(element);
}
});
//at this point, output list should have the answer
alternative answer:
List<double> first = [1,2,3,4,5,6,7];
List<double> second = [3,5,6,7,9,10];
List<double> output = first.where((element) => !second.contains(element));
note that for both cases, you need to loop over the larger list.
Upvotes: 24