tags:

views:

338

answers:

4

Hi All

I'm trying to get a distinct list of words from an array of words with the following code:

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

I thought this would take out the double occurrence of 'this' but it returns a list of each word int he phrase.

Can somebody please suggest how I can go about getting a distinct list? Thanks

Dave

+1  A: 

You haven't posted the code for your Word class, but my guess is that it doesn't implement Equals with a value comparison so you get the default implementation of Equals which just checks the object references. Note that if you decide to implement your own version of Equals, you also need to correctly implement GetHashCode.

An alternative way to solve this issue is to provide an IEqualityComparer as a parameter to the Distinct function.

Mark Byers
A: 

The problem is, that you create several Word objects that contain the same Value, but how should the compiler know, that these shall be the same items?

Try

(from w in split.Distinct()
select new Word { Text = w.ToString()}).ToList();
citronas
+4  A: 

In your example, each Word object is distinct, because there is no comparison which looks at the Text property.

However, there's no reason to create a new object:

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

Or more simply:

var distinctWords = new List<string>(split.Distinct());
James Curran
A: 

As others noted, the problem is probably that your Word object doesn't implement structural equality (compare the actual content, not instance references). If you still want to get a collection of Word objects as the result, but use Distinct on the underlying string values, you can write this:

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