My goal is to compare to lists and update values on list A with values from list B. Along with that, I want it to work like a left join and keep all values from list A even if they didn't get updated and detect multiple matches.
What I have tried so far is below.
The Setup
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UpdateMe { get; set; }
public static List<Person> CreateList()
{
return new List<Person>
{
new Person { LastName = "Barton", FirstName = "Clint" },
new Person { LastName = "Stark", FirstName = "Tony" },
new Person { LastName = "Parker", FirstName = "Peter" }
};
}
public static List<Person> CreateListTwo()
{
return new List<Person>
{
new Person { LastName = "Barton", FirstName = "Clint", UpdateMe = "Updated"},
new Person { LastName = "Stark", FirstName = "Tony", UpdateMe = "Updated"},
};
}
}
public class FirstLastNameMatch : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.FirstName == y.FirstName
&& x.LastName == y.LastName;
}
public int GetHashCode(Person obj)
{
unchecked
{
var hash = 17;
hash = hash * 23 + obj.FirstName.GetHashCode();
hash = hash * 23 + obj.LastName.GetHashCode();
return hash;
}
}
}
Implementation
static void Main()
{
var listA = Person.CreateList();
var listB = Person.CreateListTwo();
//Attempt
var result = listA.Join(
listB,
x => x,
y => y,
(x, y) => new Person
{
FirstName = x.FirstName,
LastName = x.LastName,
UpdateMe = y.UpdateMe
},
new FirstLastNameMatch()
);
foreach (var person in result)
{
Console.WriteLine($"Name: {person.FirstName} {person.LastName} " +
$"UpdateMe: {person.UpdateMe} ");
}
}
There problem I run into here is that it is only an inner join and not a left join. I have found a way to do the left join but I cannot figure out how to pass in the IEqualityComparer
into this syntax.
var result = from personA in listA
join personB in listB on new {personA.FirstName, personA.LastName } equals new { personB.FirstName, personB.LastName }
into buffer
from subPerson in buffer.DefaultIfEmpty()
select new Person
{
FirstName = personA.FirstName,
LastName = personA.LastName,
UpdateMe = (subPerson == null ? string.Empty : subPerson.UpdateMe)
};
The real catch is that once I am able to complete the left join while injecting the comparison criteria, I still need to detect duplicates.
I need to be able to identify if a person from listA
matches to more than one person in listB
. It is alright if listA
had duplicates though.
End Goal
Left join 2 lists with dynamic matching criteria.
Detect multiple matches from the right list.
I need to update a static list of properties on the left list with the match from the right list.