Search code examples
c#linqlinq-to-sql

Linq custom comparer for contains?


I have 2 lists/ enumerables. I want to compare every element with every element for both lists using LINQ (versus using say a nested loop). But, the Contains does not meet my needs because I need to do a custom comparison. I would imagine a custom comparer is what I need but not 100% sure.

I do not think this should be too difficult but not sure exactly the tool that I need for this. The 2 lists both contain distinct and different type of objects.

I could do something like this:

foreach(item i in list1)
  foreach(otherItemType in List2)
  {
    if ( CompareItem(x) ) do something;
  }

What I want to do is something like this:

var matches = myList1.Where(t => myList2.Something(t)) 

Where Something is a custom comparer. Perhaps I can override the equals comparison? I could use the .Contains but I need to do my own logic for comparison.

I thought of using the IEqualityComparer but this is set to take types of T, T and T, Y. There may be some generic constraints that I could use to solve this problem. I felt this should be easy/ simple.


Solution

  • var matches = myList1.SelectMany(
        t1 => myList2.Where(
            t2 => t2.Something(t1)
        )
    );
    

    The inner Where is like your inner foreach loop, and the outer SelectMany joins the results after iterating through as in your outer foreach loop.

    You can also make a function to do this for you (untested; can't recall extension syntax):

    public static IEnumerable<T2> MultiCompare<T1, T2>(this IEnumerable<T1> first, IEnumerable<T2> second, Func<bool, T1, T2> comparer) {
        return first.SelectMany(
            t1 => second.Where(
                t2 => comparer(t1, t2)
            )
        );
    }