Reputation: 33
I have 2 lists containing 2 different types of object. Is it possible to compare the objects from both lists and create a new list which contains objects with matching property values?
For example if I had a list of buses (with a property 'busID') and a list of drivers (also with a property 'busID'). Could I create a new list where (buses.busesID = drivers.busID)?
I realise this question is vague and contains no example code. I'm pretty stuck here though.
Upvotes: 0
Views: 1298
Reputation: 1998
If you are after a more abstract solution, then you can use reflection.
class A
{
public int x { get; set; }
public int y { get; set; }
}
class B
{
public int y { get; set; }
public int z { get; set; }
}
static List<A> listA = new List<A>();
static List<B> listB = new List<B>();
static void Main(string[] args)
{
listA.Add(new A {x = 0, y = 1});
listA.Add(new A {x = 0, y = 2});
listB.Add(new B {y = 2, z = 9});
listB.Add(new B {y = 3, z = 9});
// get all properties from classes A & B and find ones with matching names and types
var propsA = typeof(A).GetProperties();
var propsB = typeof(B).GetProperties();
var matchingProps = new List<Tuple<PropertyInfo, PropertyInfo>>();
foreach (var pa in propsA)
{
foreach (var pb in propsB)
{
if (pa.Name == pb.Name && pa.GetType() == pb.GetType())
{
matchingProps.Add(new Tuple<PropertyInfo, PropertyInfo>(pa, pb));
}
}
}
// foreach matching property, get the value from each element in list A and try to find matching one from list B
var matchingAB = new List<Tuple<A, B>>();
foreach (var mp in matchingProps)
{
foreach (var a in listA)
{
var valA = mp.Item1.GetValue(a, null);
foreach (var b in listB)
{
var valB = mp.Item2.GetValue(b, null);
if (valA.Equals(valB))
{
matchingAB.Add(new Tuple<A, B>(a, b));
}
}
}
}
Console.WriteLine(matchingAB.Count); // this prints 1 in this case
}
Sidenote: Tuple is a .NET 4 class, if you cannot use that, then you can easily write your own: Equivalent of Tuple (.NET 4) for .NET Framework 3.5
Upvotes: 0
Reputation: 10947
You can use LINQ to join these two collections on this ID, producing for example a tuple of bus and its driver. Using LINQ syntax, it would look like this:
var result = from bus in buses
join driver in drivers on bus.busID equals driver.busID
select new { Bus = bus, Driver = driver }
This may introduce several new features for you, like the LINQ itself, or anonymous type definition.
The result is a query, which is executed lazily and produces a collection of bus+driver couples.
Upvotes: 1
Reputation: 117029
Try this:
var query =
from driver in drivers
join bus in buses on driver.busID equals bus.busID
select new { driver, bus };
var results = query.ToList();
Upvotes: 0