Select unique items with LINQ
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 开发者_StackOverflow中文版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() );
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 XElement
s 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())
.
Distinct doesn't work because XElements are compared by reference, not by value. The solution is to use another overload of Distinct - Distinct(IEqualityComparer);
You need to implement IEqualityComparer for example as follows:
class XElementEqualityComparer : IEqualityComparer<XElement>
{
#region IEqualityComparer<XElement> Members
public bool Equals(XElement x, XElement y)
{
if (x == null ^ y == null)
return false;
if (x == null && y == null)
return true;
return x.Value == y.Value;
}
public int GetHashCode(XElement obj)
{
if (obj == null)
return 0;
return obj.Value.GetHashCode();
}
#endregion
}
It's not a good solution - but really easy.
foreach (XElement pic in neededFiles.Elements())
{
unSyncedPictures.Add(pic.Value);
}
List<string> temp = new List<string>();
temp.AddRange(unSyncedPictures.Distinct());
精彩评论