2009-06-16 15 views
5

Tengo una clase llamada Country. Tiene los miembros públicos, 'CountryName' y 'States'.Deje que el SequenceEqual trabaje para la lista

He declarado una lista de Países.

Ahora quiero escribir una función que acepte un nuevo 'País' y decida si CountryList ya tiene el 'País'.

he intentado escribir una función como

bool CheckCountry(Country c) 
{ 
    return CountryList.Exists(p => p.CountryName == c.Name 
           && p.States.SequenceEqual(c.States)); 
} 

Como quiero comparar Unidos utilizando la propiedad del País de los Estados, quiero modificar mi función para que SequenceEqual trabajos basados ​​en el Nombre del País de los estados?

Respuesta

12

Desglose en muchas consultas simples, y luego vuelva a poner esas consultas juntas. inicio

Vamos haciendo una secuencia de elementos que coinciden con el nombre de:

var nameMatches = from item in itemList where item.Name == p.Name select item; 

tenemos que comparar esos artículos contra la secuencia de los nombres de los subpuntos del p. ¿Cuál es esa secuencia? Escribir una consulta:

var pnames = from subitem in p.SubItems select subitem.Name; 

Ahora usted quiere encontrar todos los elementos de nameMatches donde la secuencia de los nombres de los partidos. ¿Cómo vas a obtener la secuencia de nombres? Bueno, acabamos de ver cómo hacer eso con pnames, también lo hacen la misma cosa:

var matches = from item in nameMatches 
       let subitemNames = 
        (from subitem in item.SubItems select subitem.Name) 
       where pnames.SequenceEqual(subitemNames) 
       select item; 

y ahora quiere saber, ¿hay coincidencias?

return matches.Any(); 

Eso debería funcionar igual de bien. ¡Pero si quieres ser realmente aficionado, puedes escribir todo en una gran consulta!

return (
    from item in itemList 
    let pnames = 
     (from psubitem in p.SubItems select psubitem.Name) 
    let subitemNames = 
     (from subitem in item.SubItems select subitem.Name) 
    where item.Name == p.Name 
    where pnames.SequenceEqual(subitemNames) 
    select item).Any(); 

Y listo. ¡Muy fácil! Solo recuerde, divídalo en pequeños pasos, resuelva cada problema individualmente y luego junte la solución con los resultados pequeños.

+2

realmente me he preguntado si esto ha sido escrito por alguien en el C# -team durante la lectura. resulta: ¡Eric Lippert está por supuesto en el equipo C#! – usr

1

¿Has visto la implementación de IComparer en el artículo?

1

Si lo entiendo correctamente, quiere una forma de comparar dos elementos en los que primero verifica el nombre de los dos elementos y luego verifica secuencialmente el nombre de cada subelemento. Esto es lo que quiere:

public override bool Equals(object obj) 
    { 
     return this.Name == (obj as Item).Name; 
    } 
    public override int GetHashCode() 
    { 
     return this.Name.GetHashCode(); 
    } 
    public bool Check(Item obj) 
    { 
     if (this.Name != obj.Name) 
      return false; 
     //if the lists arent of the same length then they 
     //obviously dont contain the same items, and besides 
     //there would be an exception on the next check 
     if (this.SubItems.Count != obj.SubItems.Count) 
      return false; 
     for (int i = 0; i < this.SubItems.Count; i++) 
      if (this.SubItems[i] != obj.SubItems[i]) 
       return false; 
     return true; 
    } 
Cuestiones relacionadas