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)); } 
  • 通用所有控制方法
  • LINQ:点符号与查询expression式
  • dynamicLINQ可以注入吗?
  • LINQ OrderBy与ThenBy
  • 你可以在IronPython中使用LINQtypes和扩展方法吗?
  • 左joinLINQ到实体?
  • 如何在LINQ中进行子查询
  • 使用CopyToDataTable与“new {..}”LINQ查询exception
  • 使用LINQ或其他方法,如何检查所有列表项是否具有相同的值并将其返回,如果不是则返回“otherValue”?
  • LINQ在特定属性上的Distinct()
  • Linq-to-entities – Include()方法不加载