2010-02-14 2 views
8

Ich versuche, eine bestimmte Liste von Wörtern aus einer Reihe von Wörtern mit dem folgenden Code zu erhalten:Wählen Distinct Liste der Wörter von Array mit LINQ

string words = "this is a this b"; 

var split = words.Split(' '); 

IEnumerable<Word> distinctWords = (from w in split 
          select new Word 
            { 
             Text = w.ToString() 
            } 
         ).Distinct().ToList(); 

Ich dachte, das das doppelte Auftreten herausnehmen würde 'this', aber es gibt eine Liste jedes Wortes in der Phrase zurück.

Kann mir jemand bitte vorschlagen, wie ich eine eindeutige Liste bekommen kann?

Dank

Dave

+0

Sollte nicht die 2. Zeile sein 'string [] Split = Worte. Split() '? –

+0

D'Oh! - @Mark, du hast Recht. Ich glaube, ich habe ein wenig schlampig mit meinem Kopieren/Einfügen - ich habe es jetzt behoben. Zu diesem Zeitpunkt hatte ich allerdings ein oder zwei Gläser! :-) – DaveDev

Antwort

19

In Ihrem Beispiel jedes Objekt Wort ist verschieden, weil es keinen Vergleich, die an der Eigenschaft Text aussieht, ist.

Allerdings gibt es keinen Grund, ein neues Objekt zu erstellen:

var distinctWords = (from w in split 
         select w).Distinct().ToList(); 

Oder einfacher:

var distinctWords = new List<string>(split.Distinct()); 
1

Sie haben nicht den Code für Ihre Word Klasse geschrieben, aber meine Vermutung ist, dass es nicht Equals mit einem Wertvergleich nicht implementiert, so dass Sie die Standardimplementierung von Equals erhalten, die nur das Objekt überprüft Verweise. Beachten Sie, dass Sie, wenn Sie sich entscheiden, Ihre eigene Version von Equals zu implementieren, auch GetHashCode korrekt implementieren müssen.

Eine alternative Möglichkeit, dieses Problem zu lösen, ist die Bereitstellung eines IEqualityComparer als Parameter für die Distinct-Funktion.

1

Das Problem ist, dass Sie mehrere Word-Objekte erstellen, die denselben Wert enthalten, aber wie sollte der Compiler wissen, dass diese die gleichen Elemente sein sollen?

Versuchen
(from w in split.Distinct() 
select new Word { Text = w.ToString()}).ToList(); 
0

Wie andere bereits erwähnt, das Problem ist wahrscheinlich, dass Ihr Word Objekt nicht strukturell nicht implementiert Gleichheit (vergleiche den tatsächlichen Inhalt, keine Instanzreferenzen). Wenn Sie noch eine Sammlung von Word Objekte als Ergebnis erhalten möchten, aber Distinct auf den zugrunde liegenden String-Werte verwenden, können Sie schreiben:

IEnumerable<Word> distinctWords = 
    (from w in split.Distinct() 
    select new Word { Text = w.ToString() }).ToList();