2010-08-12 63 views
6

我有一個.NET 3.5項目中的字符串類型列表。該列表中有數千個字符串,但爲了簡潔起見,我們將說它只有5個字符串。查詢僅重複列表

List<string> lstStr = new List<string>() { 
      "Apple", "Banana", "Coconut", "Coconut", "Orange"}; 

假設列表已排序(如上所述)。我需要的是一個LINQ查詢,它將刪除所有而不是重複的字符串。所以結果會給我一個只包含兩個「椰子」字符串的列表。

這可能與一個LINQ查詢?如果不是,那麼我將不得不求助於一些複雜的循環,我可以這樣做,但除非必須,否則我不想。

回答

4

這裏尋找重複的代碼格式的字符串arrya

int[] listOfItems = new[] { 4, 2, 3, 1, 6, 4, 3 }; 
var duplicates = listOfItems 
    .GroupBy(i => i) 
    .Where(g => g.Count() > 1) 
    .Select(g => g.Key); 
foreach (var d in duplicates) 
    Console.WriteLine(d); 
4

var dupes = lstStr.Where(x => lstStr.Sum(y => y==x ? 1 : 0) > 1);

OR

var dupes = lstStr.Where((x,i) => ( (i > 0 && x==lstStr[i-1]) 
            || (i < lstStr.Count-1 && x==lstStr[i+1])); 

注意,第一個枚舉列表,每一個這需要O(N²)時間(但不承擔排序列表)元素。第二個是O(n)(並且假定有排序的列表)。

0
var temp = new List<string>(); 

foreach(var item in list) 
{ 
    var stuff = (from m in list 
       where m == item 
       select m); 
    if (stuff.Count() > 1) 
    { 
     temp = temp.Concat(stuff); 
    } 
} 
1

這應該工作,並且是O(N)而不是其他答案的O(N^2)。 (注意,這確實使用了列表排序的事實,所以這確實是一個要求)。

IEnumerable<T> OnlyDups<T>(this IEnumerable<T> coll) 
    where T: IComparable<T> 
{ 
    IEnumerator<T> iter = coll.GetEnumerator(); 
    if (iter.MoveNext()) 
    { 
     T last = iter.Current; 
     while(iter.MoveNext()) 
     { 
      if (iter.Current.CompareTo(last) == 0) 
      { 
        yield return last; 
        do 
        { 
         yield return iter.Current; 
        } 
        while(iter.MoveNext() && iter.Current.CompareTo(last) == 0); 
      } 
      last = iter.Current; 
     } 
} 

使用這樣的:

IEnumerable<string> onlyDups = lstStr.OnlyDups(); 

List<string> onlyDups = lstStr.OnlyDups().ToList(); 
+0

這不使用LINQ? – McKay 2010-08-12 18:35:18

+0

@McKay:是的,但OP表示可以假定列表已排序。 – 2010-08-12 18:36:26

+0

@McKey(修改後的問題):技術上沒有,但它確實保留了一個linq樣式的接口,並且可以用作更大的LINQ語句的一部分。 – 2010-08-12 18:44:29