2010-07-10 57 views
2

我有這個集合,例如從對象的集合,獲得第二個重複項目:如何使用LINQ to對象

1:

2:乙

3:

4:C

5:

6:C

我想在LINQ查詢從這個集合的第二個重複項目,

所需要的結果是:3:A,6:C

回答

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

NB

該索引比您想要的解決方案低1(因爲索引是基於0的)。但它真的很容易增加它,甚至在第一個LINQ選擇,如果你想:

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

感謝digEmAll,它的完成:) – Homam 2010-07-10 08:48:38

+0

digEmAll,你忘了.Skip,。取並實現它自己的=) – vittore 2010-07-10 10:17:29

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調用是爲了防止secondItem從G爲兩次評估的優化。它可能並不重要,因爲我們只跳過1,但它可能的問題,如果我們開始跳繩100


下面是使用地點和拍攝的可變另一種解決方案。

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