使用LINQ选择唯一项

4
当我使用以下代码时,我会多次获得相同的项目。
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));

我希望获得唯一的项目。我看到了一个Stack Overflow的帖子,如何使用LINQ进行SELECT UNIQUE?,它使用了这个方法,我尝试实现它,但是改变没有任何影响。
代码:
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() );
3个回答

7

我认为这个方法不起作用的原因是 XElement.Equals 使用简单的引用相等检查而不是比较两个项目的 Value 属性。如果你想比较值,可以将其更改为:

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

你也可以创建自己的 IEqualityComparer<T> 用于比较两个 XElement 的值。需要注意的是,这假定所有的值都不为 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();
    }
}

然后,您可以用 Distinct(new XElementValueEqualityComparer()) 替换现有的对 Distinct 的调用。

尽管由于时间问题我不得不实现一个糟糕的解决方案,但我仍然期待测试和学习您的解决方案 - 谢谢Asaf。 - Asaf

4

Distinct方法无法正常工作,因为XElements之间的比较是通过引用而不是值进行的。解决方法是使用另一个重载的Distinct方法——Distinct(IEqualityComparer)。

您需要实现IEqualityComparer,例如如下:

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
    }

1
李的答案更好,因为它更紧凑。我只是留下我的作为例子。 - ILya
+1 感谢您的回答,以及建议使用他人的解决方案。 - Asaf

0

这不是一个好的解决方案 - 但真的很容易。

foreach (XElement  pic in neededFiles.Elements())
{
    unSyncedPictures.Add(pic.Value);
}
List<string> temp = new List<string>();
temp.AddRange(unSyncedPictures.Distinct());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接