如何使用LINQ to object从对象集合中获取第二个重复项

时间:2010-07-10 08:37:14

标签: c# linq linq-to-objects

我以此集合为例:

1:A

2:B

3:A

4:C

5:A

6:C

我想在LINQ查询中获取此集合中的第二个重复项

所需的结果是:3:A,6:C

2 个答案:

答案 0 :(得分:2)

有点复杂但有效:

int occ = 1; // 1 if you want the 2nd occurrence, 2 if you want the 3rd etc...
var nRepeatingElements = list.Select((x, idx) => new { Index = idx, Value = x })
                                .GroupBy(x => x.Value)
                                .Where(g => g.Count() > occ)
                                .Select(x => x.ElementAt(occ))
                                .ToList();

它返回一个列表:

[Index:2 , Value: 'A']
[Index:5 , Value: 'C']

N.B。

索引比您想要的解决方案低1(因为索引从0开始)。但是如果你想要的话,即使在第一个LINQ Select中也可以很容易地增加它:

Select((x, idx) => new { Index = idx+1, Value = x })

答案 1 :(得分:1)

IEnumerable<Item> result =
  from item in items
  group item by item.Key into g
  let secondItem = g.Skip(1).Take(1) //.ToList()
  where secondItem.Any()
  select secondItem.First()

ToList调用是一种优化,可以防止secondgtem从g计算两次。这可能没关系,因为我们只跳过1,但如果我们开始跳过100则可能很重要。


这是使用Where和捕获变量的另一种解决方案。

HashSet<Item.Key> seenIt = new HashSet<Item.Key>();
HashSet<Item.Key> returnedIt = new HashSet<Item.Key>();

IEnumerable<Item> result =
  items.Where(item => 
{
  key = Item.Key;
  if (!seenIt[key])
  {
    seenIt.Add(key);
  }
  else if (!returnedIt[key])
  {
    returnedIt.Add(key)
    return true;
  }
  return false;
});