【问题标题】:Get Non-Distinct elements from an IEnumerable从 IEnumerable 获取非不同元素
【发布时间】:2010-01-24 14:46:24
【问题描述】:

我有一个名为 Item 的类。 Item 有一个名为 ItemCode 的标识符属性,它是一个字符串。我想在项目列表中获取所有非不同项目的列表。

例子:

List<Item> itemList = new List<Item>()
{
   new Item("code1", "description1"),
   new Item("code2", "description2"),
   new Item("code2", "description3"),
};

我想要一个包含底部两个条目的列表

如果我使用

var distinctItems = itemsList.Distinct();

我得到了很棒的不同项目的列表,但我想要的几乎相反。我可以从原始列表中减去不同的列表,但它不会包含所有重复,每个重复只有一个实例。

我玩了一场,但想不出一个优雅的解决方案。任何指示或帮助将不胜感激。谢谢!

我有 3.5,所以 LINQ 可用

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    我的看法:

    var distinctItems = 
        from list in itemsList
        group list by list.ItemCode into grouped
        where grouped.Count() > 1
        select grouped;
    

    【讨论】:

    • 感谢 magnus(和 Thomas),我不会想到使用 GroupBy
    • 为了清楚起见,我建议将变量名称更改为 nonDistinctItems。很好的答案,不过我用这个作为解决方案。
    【解决方案2】:

    作为扩展方法:

    public static IEnumerable<T> NonDistinct<T, TKey> (this IEnumerable<T> source, Func<T, TKey> keySelector)
    {
       return source.GroupBy(keySelector).Where(g => g.Count() > 1).SelectMany(r => r);
    }
    

    【讨论】:

      【解决方案3】:

      您可能想尝试使用 group by 运算符。我们的想法是按 ItemCode 对它们进行分组,并采用包含多个成员的组,例如:

      var grouped = from i in itemList
                    group i by i.ItemCode into g
                    select new { Code = g.Key, Items = g };
      
      var result = from g in grouped 
                   where g.Items.Count() > 1;
      

      【讨论】:

      • 我无法编译。它抱怨“group by”和“into”语句
      • 我忘记了 group 和 by 之间的“i” :$ 现在它已经修复了,但它基本上和 magnus 写的一样。
      【解决方案4】:

      我建议编写一个自定义扩展方法,如下所示:

      static class RepeatedExtension
      {
          public static IEnumerable<T> Repeated<T>(this IEnumerable<T> source)
          {
              var distinct = new Dictionary<T, int>();
              foreach (var item in source)
              {
                  if (!distinct.ContainsKey(item))
                      distinct.Add(item, 1);
                  else
                  {
                      if (distinct[item]++ == 1) // only yield items on first repeated occurence
                          yield return item;
                  }                    
              }
          }
      }
      

      您还需要为您的 Item 类重写 Equals() 方法,以便通过它们的代码正确比较项目。

      【讨论】:

        猜你喜欢
        • 2020-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多