2010-09-16 4 views
4

Lorsque j'utilise le code suivant, j'obtiens les mêmes éléments plusieurs fois.Sélectionnez des éléments uniques avec 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)); 

Je ne souhaite recevoir que des éléments uniques. J'ai vu un poste de dépassement de pile, How can I do SELECT UNIQUE with LINQ?, qui l'a utilisé, et j'ai essayé de l'implémenter, mais le changement n'a eu aucun effet.

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

Répondre

7

j'imagine que la raison pour laquelle cela ne fonctionne pas parce que XElement.Equals utilise une simple vérification de l'égalité de référence plutôt que de comparer les Value propriétés des deux éléments. Si vous voulez comparer les valeurs, vous pouvez le modifier à:

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

Vous pouvez aussi créer votre propre IEqualityComparer<T> pour comparer deux XElement s par leurs valeurs. Notez que cela suppose que toutes les valeurs sont non nulles:

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

Ensuite, vous pouvez remplacer l'appel existant à Distinct avec Distinct(new XElementValueEqualityComparer()).

+0

+1 en dépit du fait que je devais mettre en oeuvre une mauvaise solution en raison de problèmes de temps, je suis impatient de tester et d'apprendre votre solution - grâce Asaf – Asaf

4

La distinction ne fonctionne pas car les XElements sont comparés par référence et non par valeur. La solution consiste à utiliser une autre surcharge de Distinct - Distinct (IEqualityComparer);

Vous devez mettre en œuvre IEqualityComparer par exemple comme suit:

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

réponse de Lee est meilleur parce qu'il est plus compact. Je laisse le mien simplement par exemple – ILya

+0

+ 1 merci pour l'unwer + le conseil rare d'utiliser quelqu'un d'autre solution. – Asaf

0

Ce n'est pas une bonne solution - mais vraiment facile.

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