Reputation: 53
I want to compare two different lists with one property in common (Name). I have tried things like the .Contains() method, but that does not work because I am dealing with lists of two different objects. I have tried the solutions in questions like:
C# Compare Two Lists of Different Objects
C#, compare two different type of lists
compare different type of list in c#
But these solutions do not work because my lists expect a Property or Animal object and not a "string", this is where I get stuck.
I have two classes:
public class Animal
{
public string Name = string.Empty;
public string XChromosome = string.Empty;
public string YChromosome = string.Empty;
}
public class Properties
{
public string Name = string.Empty;
public string Prop1 = string.Empty;
public string Prop2 = string.Empty;
}
The two lists look like this:
List<Animal> = "name", "xposition", "yposition"
"name1", "xposition1", "yposition1" etc..
List<Properties> = "name", "prop1","prop2"
"name1", "prop3", "prop4" etc..
What I would like to do do is, compare these two lists and if the "Name" matches I would like to get the content of both lists belonging to this name. I also tried using a HashSet or a Dictionary, but this is not what I am looking for.
Upvotes: 5
Views: 2201
Reputation: 76424
Sergey Berezovsky's solution is good, deserves all the upvotes and to be the accepted answer, however, I would like to add an alternative as well. You could create a class
called Named
, like this:
class Named {
public string Name = string.Empty;
}
and inherit your class
es from it, like this:
public class Animal : Named
{
public string XChromosome = string.Empty;
public string YChromosome = string.Empty;
}
public class Properties : Named
{
public string Prop1 = string.Empty;
public string Prop2 = string.Empty;
}
This will enable you to use List<Named>
as type which will allow you to do your task easily either with LINQ or with a cycle. The benefit of this approach is that you will not duplicate the same member in both class
es and if you are going to have more cases when you need to do something like this or you are going to have more similar members and/or methods, then you will not duplicate your code.
Upvotes: 1
Reputation: 236188
You can join two lists on Name
property and get matches as anonymous object:
from a in animals
join p in properties on a.Name equals p.Name
select new {
a.Name,
a.XChromosome,
a.YChromosome,
p.Prop1,
p.Prop2
}
You can try it yourself in .NET Fiddle.
NOTE: If you want to get animal info no matter if there is match in properties, or you can have more than one match for given animal, then you need to use group join (check this fiddle for details):
from a in animals
join p in properties on a.Name equals p.Name into g
from p in g.DefaultIfEmpty()
select new {
a.Name,
a.XChromosome,
a.YChromosome,
Prop1 = p?.Prop1,
Prop2 = p?.Prop2
}
That wil return each pair of animal - property joined by name. If no matching property found, then Prop1 and Prop2 will have null values by default (though you can provide any default value you want).
Upvotes: 11