从IEnumerable中获取非独特元素

时间:2010-01-24 14:46:25

标签: c# linq

我有一个名为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可用

4 个答案:

答案 0 :(得分:16)

我的看法:

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

答案 1 :(得分:14)

作为扩展方法:

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

答案 2 :(得分:2)

您可能希望使用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;

答案 3 :(得分:0)

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

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()方法,以便通过代码正确比较项目。