2009-06-16 9 views
5

Ho una classe denominata Paese. Ha i membri pubblici, "CountryName" e "States".Lascia che SequenceEqual funzioni per l'elenco

Ho dichiarato un elenco di Paesi.

Ora voglio scrivere una funzione che accetta un nuovo "Paese" e decide se CountryList ha già il "Paese".

ho provato a scrivere una funzione come

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

come voglio confrontare Uniti utilizzando la proprietà CountryName degli Stati, voglio modificare la mia funzione in modo che SequenceEqual Funziona sulla base del CountryName degli stati?

risposta

12

Scomposizione in molte query semplici e quindi ricomporre quelle query. inizio

Let facendo una sequenza di elementi che corrispondono al nome:

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

Abbiamo bisogno di confrontare le voci contro la sequenza dei nomi a elementi secondari di p. Qual è quella sequenza? Scrivere una query:

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

Ora si desidera trovare tutti gli elementi da nameMatches in cui la sequenza dei nomi partite. Come hai intenzione di ottenere la sequenza di nomi? Beh, abbiamo appena visto come fare con pnames, in modo da fare la stessa cosa:

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

e ora si vuole sapere, ci sono le partite?

return matches.Any(); 

Che dovrebbe funzionare bene così com'è. Ma se vuoi essere davvero appassionato puoi scrivere il tutto in un'unica grande query!

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(); 

E il gioco è fatto. Facile come torta! Basta ricordare, scomporlo in piccoli passi, risolvere ogni problema individualmente e quindi mettere insieme la soluzione dei piccoli risultati.

+2

Mi sono davvero chiesto se questo è stato scritto da qualcuno sul C# -team durante la lettura. scopre: Eric Lippert è ovviamente sul C# -team! – usr

1

Hai guardato all'implementazione di IComparer sull'elemento?

1

Se ho capito bene, vuoi un modo per confrontare due elementi in cui controlli per la prima volta il nome dei due elementi, quindi controlla in sequenza il nome di ciascun elemento secondario. Ecco cosa vuoi:

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