Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select unique items with LINQ

Tags:

c#

linq

distinct

When I use the following code I get the same items multiple times.

XElement neededFiles = new XElement("needed",
    from o in _9nFiles.Elements()
    join t in addedToSitePull.Elements()
         on o.Value equals
         t.Value
    where o.Value == t.Value
    select new XElement("pic", o.Value));

I'd like to get only unique items. I saw a Stack Overflow post, How can I do SELECT UNIQUE with LINQ?, that used it, and I tried to implement it, but the change had no affect.

The code:

XElement neededFiles = new XElement("needed",
(from o in _9nFiles.Elements()
join t in addedToSitePull.Elements()
on o.Value equals
 t.Value
 where o.Value == t.Value
select new XElement("pic", o.Value)).Distinct() );
like image 397
Asaf Avatar asked Dec 22 '22 23:12

Asaf


1 Answers

I imagine the reason this doesn't work is because XElement.Equals uses a simple reference equality check rather than comparing the Value properties of the two items. If you want to compare the values, you could change it to:

_9nfiles.Elements()
    .Join(addedToSitePull, o => o.Value, t => t.Value, (o, t) => o.Value)
    .Distinct()
    .Select(val => new XElement("pic", val));

You could also create your own IEqualityComparer<T> for comparing two XElements by their values. Note this assumes all values are non-null:

public class XElementValueEqualityComparer : IEqualityComparer<XElement>
{
    public bool Equals(XElement x, XElement y)
    {
        return x.Value.Equals(y.Value);
    }

    public int GetHashCode(XElement x)
    {
        return x.Value.GetHashCode();
    }
}

Then you could replace the existing call to Distinct with Distinct(new XElementValueEqualityComparer()).

like image 118
Lee Avatar answered Jan 03 '23 12:01

Lee