C# - Comparing Items Between 2 Lists

How can I compare two lists of objects with ingorance of order?

If you don't have any duplicates, and you just want to see whether both lists contain the same set of IDs, then this is a set operation and the easiest solution uses a HashSet<int>:

bool same = list1.Select(x => x.Id).ToHashSet().SetEquals(list2.Select(x => x.Id));

You can optimize by checking the lengths of your two lists first: if they're different lengths, they're obviously different:

bool same = list1.Count == list2.Count &&
list1.Select(x => x.Id).ToHashSet().SetEquals(list2.Select(x => x.Id));

If you want to get the objects which are different between the two lists, you can use HashSet<T>.SymmetricExceptWith. The problem here is that we now need to be comparing Person objects directly, rather than taking their IDs first, because need those Person object out of the other side.

Therefore, we'll need to write our own IEqualityComparer:

public class PersonIdComparer : IEqualityComparer<Person>
public bool Equals(Person x, Person y) => x.Id == y.Id;
public int GetHashCode(Person x) => x.Id.GetHashCode();

var set = list1.ToHashSet(new PersonIdComparer());
// set now contains the differences

Comparing items in 2 lists in c#

Use the Zip extension method.

var result = firstList.Zip(secondList, (a, b) => a == b);

Is there a list to compare the properties of items between two lists?

If ordering is guaranteed, then by zipping the two lists together, you can do the following:

var diffs = list1.Zip(list2, (item1, item2) => (item1, item2))
.Where(x => x.item1.myAwesomeProperty != x.item2.myAwesomeProperty)
.Select(x => x.item1); //.ToList()

If ValueTuple isn't available at your language level, then use anonymous object instead:

var diffs = list1.Zip(list2, (item1, item2) => new{item1, item2})
.Where(x => x.item1.myAwesomeProperty != x.item2.myAwesomeProperty)
.Select(x => x.item1); //.ToList()

C# Compare two list of same object type

It looks like you need rows to satisfy two conditions, not one, in order to make the output:

  • There needs to be a match on id and symbol, and
  • There must be no match on id, symbol, and code.

Here is how to do that with LINQ directly:

var tmp = list1.Where(x=>
list2.Any(z=>x.id==z.id && x.symbol==z.symbol)
&& !list2.Any(z => x.id==z.id && x.symbol==z.symbol && x.code==z.code));


An alternative based on applying De Morgan's laws:

var tmp = list1.Where(x=>
list2.Any(z=>x.id==z.id && x.symbol==z.symbol)
&& list2.All(z => x.id!=z.id || x.symbol!=z.symbol || x.code!=z.code));


Compare two lists to determine if both lists contain same items using lambda predicates

var containsAll = typeList.All(type => 
wList.Any(widget => widget.bearing.Equals(type)));

Translated, it is true for all types in typeList that any (at least one) widget in the list has that type.

How to compare two lists with multiple objects and set values?

For filtering you can use LINQ, to set the values use a loop:

var commonItems = from x in list1
join y in list2
on x.Name equals y.Name
select new { Item = x, NewValue = y.Value };

foreach(var x in commonItems)
x.Item.Value = x.NewValue;

Related Topics

Leave a reply