2010-09-16 4 views
4

Когда я использую следующий код, я получаю одни и те же элементы несколько раз.Выберите уникальные элементы с LINQ

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, How can I do SELECT UNIQUE with LINQ?, который использовал его, и я попытался его реализовать, но изменение не повлияло.

Код:

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

ответ

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 сек их значения. Обратите внимание, это предполагает, что все значения ненулевые:

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 с Distinct(new XElementValueEqualityComparer()).

+0

+1, несмотря на то, что я должен был осуществить плохое решение, из-за проблем времени, я с нетерпением жду, чтобы проверить и узнать ваше решение - благодаря Асаф – 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

+0

+1 спасибо за ответ + редкий совет использовать какое-то другое решение. – Asaf

0

Это не очень хорошее решение - но на самом деле легко.

foreach (XElement pic in neededFiles.Elements()) 
{ 
    unSyncedPictures.Add(pic.Value); 
} 
List<string> temp = new List<string>(); 
temp.AddRange(unSyncedPictures.Distinct()); 
Смежные вопросы