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.Spl开发者_开发问答it(' ');
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
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());
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();
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.
You may try to convert array ToList() first before calling the .Distinct() and then converting it ToArray() again
myArray= myArray.ToList().Distinct().ToArray();
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();
精彩评论