代码之家  ›  专栏  ›  技术社区  ›  Homam

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

  •  2
  • Homam  · 技术社区  · 15 年前

    1:A

    2:乙

    3:A

    4:C

    我想在LINQ查询中从这个集合中获取第二个重复项,

    要求的结果是:3:A,6:C

    2 回复  |  直到 15 年前
        1
  •  2
  •   digEmAll    15 年前

    有点复杂但很有效:

    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']
    

    注意。

    Select((x, idx) => new { Index = idx+1, Value = x })
    
        2
  •  1
  •   Amy B    15 年前
    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调用是一种优化,可以防止secondItem从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;
    });