Quiero comparar dos listas diferentes con una propiedad en común (Nombre). He intentado cosas como el método .Contains (), pero eso no funciona porque estoy tratando con listas de dos objetos diferentes. He probado las soluciones en preguntas como:

C # Compare dos listas de diferentes objetos

C #, compara dos tipos diferentes de listas

compare diferentes tipos de lista en c #

Pero estas soluciones no funcionan porque mis listas esperan un objeto Property o Animal y no una "cadena", aquí es donde me atoro.

Tengo dos clases:

 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;
}

Las dos listas se ven así:

List<Animal> = "name", "xposition", "yposition"
               "name1", "xposition1", "yposition1" etc..

List<Properties> = "name", "prop1","prop2"
                   "name1", "prop3", "prop4" etc..  

Lo que me gustaría hacer es comparar estas dos listas y si el "Nombre" coincide, me gustaría obtener el contenido de ambas listas que pertenecen a este nombre. También intenté usar un HashSet o un Diccionario, pero esto no es lo que estoy buscando.

c#
4
E.O. 6 mar. 2017 a las 11:40

2 respuestas

La mejor respuesta

Puede unirse dos listas en {{ X0}} y obtener coincidencias como objeto anónimo:

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
}

Puede probarlo usted mismo en .NET Fiddle.


NOTA: Si desea obtener información sobre animales sin importar si hay coincidencia en las propiedades, o si puede tener más de una coincidencia para un animal determinado, debe usar unirse al grupo (verifique este violín para más detalles):

  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
  }

Eso devolverá cada par de animales - propiedad unida por nombre. Si no se encuentra ninguna propiedad coincidente, Prop1 y Prop2 tendrán valores nulos de forma predeterminada (aunque puede proporcionar cualquier valor predeterminado que desee).

11
Sergey Berezovskiy 6 mar. 2017 a las 09:03

La solución de Sergey Berezovsky es buena, merece todos los votos a favor y para ser la respuesta aceptada, sin embargo, también me gustaría agregar una alternativa. Puede crear un class llamado Named, así:

class Named {
    public string Name = string.Empty;
}

Y herede sus class es de él, así:

 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;
}

Esto le permitirá usar List<Named> como tipo que le permitirá realizar su tarea fácilmente, ya sea con LINQ o con un ciclo. El beneficio de este enfoque es que no duplicará el mismo miembro en ambos class es y si va a tener más casos cuando necesite hacer algo como esto o tendrá más miembros similares y / o métodos, entonces no duplicará su código.

1
Lajos Arpad 6 mar. 2017 a las 09:19