2010-02-14 20 views
8

Sto cercando di ottenere una lista distinta di parole da un array di parole con il seguente codice:Selezionare distinto elenco di parole da Array con 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(); 

ho pensato che questo sarebbe togliere la doppia presenza di 'this' ma restituisce una lista di ogni parola nella frase.

Qualcuno può suggerire come posso ottenere un elenco distinto? Grazie

Dave

+0

Non dovrebbe essere la linea 2 'string [] = dividere parole. Split() '? –

+0

D'Oh! - @ Mark, hai ragione. Credo di essere un po 'sciatto con il mio copia/incolla - l'ho risolto ora. Avevo avuto uno o due bicchieri in quel momento però! :-) – DaveDev

risposta

19

Nel tuo esempio, ogni oggetto Word è distinta, perché non c'è paragone che guarda la proprietà Text.

Tuttavia, non c'è alcun motivo per creare un nuovo oggetto:

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

O più semplicemente:

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

Non hanno inviato il codice per la classe Word, ma la mia ipotesi è che non implementa Equals con un confronto il valore in modo da ottenere l'implementazione predefinita di Equals che ha appena controlla l'oggetto Riferimenti. Si noti che se si decide di implementare la propria versione di Equals, è necessario implementare correttamente GetHashCode.

Un modo alternativo per risolvere questo problema è fornire un parametro IEqualityComparer come parametro per la funzione Distinct.

1

Il problema è che si creano diversi oggetti di Word che contengono lo stesso valore, ma come dovrebbe sapere il compilatore, che questi devono essere gli stessi elementi?

Prova

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

Come altri hanno notato, il problema è probabilmente che l'oggetto Word non implementa strutturale uguaglianza (confrontare il contenuto attuale, non i riferimenti all'istanza). Se si vuole ancora ottenere una raccolta di Word oggetti come il risultato, ma utilizzare Distinct sui valori di stringa sottostanti, è possibile scrivere questo:

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