Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to get distinct values from two List<int> objects

Tags:

.net

.net-3.5

I have 2 List objects:

List<int> lst1 = new List<int>();
List<int> lst2 = new List<int>();

Let's say they have values:

lst1.Add(1);
lst1.Add(2);
lst1.Add(3);
lst1.Add(4);

lst2.Add(1);
lst2.Add(4);

I need to get an object containing the "distinct" list of both of these; so in this case the return would be List {2, 3}.

Is there an easy way to do this? Or do I need to iterate through each value of the lists and compare?

I am open to using ObjectQuery, LINQ, etc as these lists are coming from a database, and could potentially be several hundred to several thousand entries long.

Thanks!

like image 595
SlackerCoder Avatar asked Apr 01 '10 15:04

SlackerCoder


People also ask

How do I find unique values between two lists?

A simple way to get unique values from a list where the values will not change is to use the Remove Duplicates functionality, which can be found under the Data menu. First, copy the State column from one of the two data sets.

How do I get unique elements from two lists in Python?

Using Python's import numpy, the unique elements in the array are also obtained. In the first step convert the list to x=numpy. array(list) and then use numpy. unique(x) function to get the unique values from the list.


2 Answers

Ahmad is nearly right with Except, I believe - but that won't give you items which are in lst2 but not in lst1. So in the example you gave, if you added 5 to lst2, I imagine you'd want the result to be {2, 3, 5}. In that case, you want a symmetric difference. I don't think there's any way to do that directly in LINQ to Objects in a single call, but you can still achieve it. Here's a simple but inefficient way to do it:

lst1.Union(lst2).Except(lst1.Intersect(lst2)).ToList();

(Obviously you only need ToList() if you genuinely need a List<T> instead of an IEnumerable<T>.)

The way to read this is "I want items that are in either list but not in both."

It's possible that it would be more efficient to use Concat - which would still work as Except is a set based operator which will only return distinct results:

lst1.Concat(lst2).Except(lst1.Intersect(lst2)).ToList();
like image 132
Jon Skeet Avatar answered Sep 20 '22 19:09

Jon Skeet


EDIT: thanks to the comments you need to do some extra work besides just using Except to get a symmetric difference. If an additional value is added to the 2nd list Except alone would be incorrect. To get the proper result try this:

var list1 = new List<int>(Enumerable.Range(1,4));
var list2 = new List<int> { 1, 4, 6 };

var result = list1.Except(list2).Union(list2.Except(list1));

The above returns {2, 3, 6}.

Note that you'll need to add a ToList() if you really need a List<int>, otherwise the above operation will return an IEnumerable<int>.


Use the Enumerable.Except method, which produces the set difference of two sequences:

var result = lst1.Except(lst2);
like image 26
Ahmad Mageed Avatar answered Sep 18 '22 19:09

Ahmad Mageed