Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to get matching items from two list c#

I have two lists

List1 Only two property. Cant use Dictionary since there might be duplicate keys. The combination of Property1 and Property2 is unique.

public class List1
{
    public string Property1 { get; internal set; }
   public string Property2 { get; internal set; }
}

public class List2
{
    public string Property1 { get; internal set; }
    public string Property2 { get; internal set; }
    public string Property3 { get; internal set; }
}

List<List1> mylist1 = new List<List1>() {
    new List1() {Property1="664",Property2="Ford" },
    new List1() {Property1="665",Property2="Ford" },
    new List1() {Property1="664",Property2="Toyota" },
};

List<List2> mylist2 = new List<List2>() {
    new List2() {Property1="664",Property2="Ford" ,Property3="USA"},
    new List2() {Property1="665",Property2="Ford" ,Property3="USA"},
    new List2() {Property1="664",Property2="Toyota" ,Property3="USA"},
    new List2() {Property1="666",Property2="Toyota" ,Property3="USA"},
};

I need to get the matching items in mylist1 and mylist2. The match should happen only on Property1 and Property2. Property3 in the mylist2 can be ignored during comparison.

Currently I use

var matchingCodes = mylist1.Where(l1 => mylist2.Any(l2 => (l2.Property1 == l1.Property1 && l2.Property2==l1.Property2))).ToList();

which works perfectly fine. But is there a better way/ fastest way to do this?

I can change List1 to any other Type. but not List2.

like image 492
Gokul Avatar asked Oct 12 '25 09:10

Gokul


2 Answers

You could also do a join:

var query= from l in mylist1
           join e in mylist2 on new {Property1=l.Property1,Property2=l.Property2} equals new {Property1=e.Property1,Property2=e.Property2}
           select l;
like image 122
octavioccl Avatar answered Oct 13 '25 22:10

octavioccl


The easiest way to do it in Linq which is relatively fast, or atleast faster than your approach is using Join or GroupJoin like so:

List<List1> matchingCodes = mylist1.GroupJoin(mylist2,

               l1 => new { l1.Property1, l1.Property2 },// Define how the key from List1 looks like
               l2 => new { l2.Property1, l2.Property2 },// Define how the key from List2 looks like

               // Define what we select from the match between list1 and list2
               (l1Item, l2Items) => l1Item).ToList();

Simplified, this creates two dictionaries which are then joined together.

GroupJoin works better here as it gives you the item from List1 and all matching from list2.

A regular Join would return the same item from List1 per match from List2.

See also Enumerable.GroupJoin (C# Reference)

Note this is the equivalent to @octavioccl's answer. Also this example assumes, the names of the properties from both classes are equal. If they arent you have to modifiy they keyselectors abit like so:

l1 => new { A=l1.Foo, B=l1.Bar},
l2 => new { A=l2.Herp, B=l2.Derp},
like image 35
CSharpie Avatar answered Oct 13 '25 23:10

CSharpie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!