E.O.
E.O.

Reputation: 53

Compare items of two different type of lists c#

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

Answers (2)

Lajos Arpad
Lajos Arpad

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 classes 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 classes 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

Sergey Berezovskiy
Sergey Berezovskiy

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

Related Questions