LINQ:不同的值

我从XML中设置了以下项目:

id category 5 1 5 3 5 4 5 3 5 3 

我需要这些项目的一个清楚的名单:

 5 1 5 3 5 4 

LINQ中如何区分类别和ID?

你是否试图通过一个以上的领域来区分? 如果是这样,只要使用匿名types和Distinct运算符,它应该没问题:

 var query = doc.Elements("whatever") .Select(element => new { id = (int) element.Attribute("id"), category = (int) element.Attribute("cat") }) .Distinct(); 

如果您试图获得“较大”types的一组不同的值,但仅查看独立性方面的一些属性子集,则可能需要在DistinctBy.cs中的MoreLINQ中实现DistinctBy.cs

  public static IEnumerable<TSource> DistinctBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) { HashSet<TKey> knownKeys = new HashSet<TKey>(comparer); foreach (TSource element in source) { if (knownKeys.Add(keySelector(element))) { yield return element; } } } 

(如果您作为比较器传入null ,则将使用默认比较器作为键types。)

只需使用Distinct()与你自己的比较器。

http://msdn.microsoft.com/en-us/library/bb338049.aspx

除了Jon Skeet的回答,你还可以使用expression式组来获得每个组迭代的w / a计数的唯一组:

 var query = from e in doc.Elements("whatever") group e by new { id = e.Key, val = e.Value } into g select new { id = g.Key.id, val = g.Key.val, count = g.Count() }; 

对于任何一个仍在寻找; 这里是另一种实现自定义lambda比较器的方法。

 public class LambdaComparer<T> : IEqualityComparer<T> { private readonly Func<T, T, bool> _expression; public LambdaComparer(Func<T, T, bool> lambda) { _expression = lambda; } public bool Equals(T x, T y) { return _expression(x, y); } public int GetHashCode(T obj) { /* If you just return 0 for the hash the Equals comparer will kick in. The underlying evaluation checks the hash and then short circuits the evaluation if it is false. Otherwise, it checks the Equals. If you force the hash to be true (by assuming 0 for both objects), you will always fall through to the Equals check which is what we are always going for. */ return 0; } } 

你可以创build一个linq Distinct的扩展,它可以使用lambda的

  public static IEnumerable<T> Distinct<T>(this IEnumerable<T> list, Func<T, T, bool> lambda) { return list.Distinct(new LambdaComparer<T>(lambda)); } 

用法:

 var availableItems = list.Distinct((p, p1) => p.Id== p1.Id); 

我的答案有点迟,但是如果你想要整个元素,你可能想要做到这一点,而不是你想要分组的值:

 var query = doc.Elements("whatever") .GroupBy(element => new { id = (int) element.Attribute("id"), category = (int) element.Attribute("cat") }) .Select(e => e.First()); 

这将给你第一个整体元素通过select匹配你的组,很像Jon Skeets第二个使用DistinctBy的例子,但是没有实现IEqualityComparer比较器。 DistinctBy很可能会更快,但是如果性能不是问题,上面的解决scheme将涉及更less的代码。

 // First Get DataTable as dt // DataRowComparer Compare columns numbers in each row & data in each row IEnumerable<DataRow> Distinct = dt.AsEnumerable().Distinct(DataRowComparer.Default); foreach (DataRow row in Distinct) { Console.WriteLine("{0,-15} {1,-15}", row.Field<int>(0), row.Field<string>(1)); }