2010-08-12 30 views
6

Tôi có một Danh sách loại chuỗi trong dự án .NET 3.5. Danh sách có hàng ngàn chuỗi trong đó, nhưng vì lợi ích của ngắn gọn, chúng ta sẽ nói rằng nó chỉ có 5 chuỗi trong đó.Truy vấn danh sách chỉ cho các bản sao

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

Giả sử danh sách được sắp xếp (như bạn có thể nói ở trên). Những gì tôi cần là truy vấn LINQ sẽ xóa tất cả các chuỗi là không phải là trùng lặp. Vì vậy, kết quả sẽ để lại cho tôi một danh sách chỉ chứa hai chuỗi "Dừa".

Điều này có thể thực hiện với truy vấn LINQ không? Nếu nó không phải là sau đó tôi sẽ phải nghỉ mát đến một số phức tạp cho các vòng, mà tôi có thể làm, nhưng tôi không muốn trừ khi tôi đã phải.

Trả lời

4

ở đây là mã cho việc tìm kiếm các bản sao hình thành chuỗi 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);

HOẶC

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

Lưu ý rằng người đầu tiên liệt kê danh sách cho mọi phần tử trong đó có O (n ²) thời gian (nhưng không thừa nhận một danh sách được sắp xếp). Cách thứ hai là O (n) (và giả định danh sách được sắp xếp).

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

Điều này sẽ hoạt động và là O (N) thay vì O (N^2) của các câu trả lời khác. (Lưu ý, điều này không sử dụng thực tế là danh sách được sắp xếp, do đó thực sự là một yêu cầu).

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

Sử dụng nó như thế này:

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

hoặc

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

này không sử dụng LINQ? – McKay

+0

@McKay: Có, nhưng OP đã tuyên bố rằng có thể giả định rằng danh sách được sắp xếp. –

+0

@McKey (câu hỏi được sửa đổi): về mặt kỹ thuật không, nhưng nó duy trì một giao diện kiểu LINQ, và có thể được sử dụng như một phần của một câu lệnh LINQ lớn hơn. –

Các vấn đề liên quan