2010-02-14 4 views
8

J'essaie d'obtenir une liste distincte de mots d'un tableau de mots avec le code suivant:Sélectionnez Liste Distinct des mots de tableau avec 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(); 

Je pensais que ce serait prendre la double occurrence de 'ceci' mais il retourne une liste de chaque mot dans sa phrase.

Quelqu'un peut-il suggérer comment je peux obtenir une liste distincte? Merci

Dave

+0

Ne devrait pas la 2ème ligne est 'string [] Scinder = mots. Split() '? –

+0

D'Oh! - @Mark, tu as raison. Je suppose que j'ai un peu bâclé avec mon copier/coller - je l'ai réparé maintenant. J'avais cependant un ou deux verres à ce stade! :-) – DaveDev

Répondre

19

Dans votre exemple, chaque objet Word est distincte, parce qu'il n'y a pas de comparaison qui regarde la propriété Text.

Cependant, il n'y a aucune raison de créer un nouvel objet:

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

Ou plus simplement:

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

Vous avez pas posté le code de votre Word classe, mais je pense qu'il ne met pas en œuvre Equals avec une comparaison de la valeur afin que vous obteniez l'implémentation par défaut de Equals qui vérifie simplement l'objet les références. Notez que si vous décidez d'implémenter votre propre version de Equals, vous devez également implémenter correctement GetHashCode.

Une autre façon de résoudre ce problème consiste à fournir un IEqualityComparer en tant que paramètre à la fonction Distinct.

1

Le problème est que vous créez plusieurs objets Word qui contiennent la même valeur, mais comment le compilateur doit-il savoir qu'il s'agit des mêmes éléments?

Essayez

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

Comme d'autres ont noté, le problème est probablement que votre objet Word ne met pas en œuvre structurelle égalité (comparez le contenu réel, pas les références d'instance). Si vous voulez toujours obtenir une collection de Word objets que le résultat, mais utiliser Distinct sur les valeurs de chaîne sous-jacentes, vous pouvez écrire ceci:

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