2013-04-07 36 views
7

tôi có:Cách tìm các mục trùng lặp trong danh sách <>?

List<string> list = new List<string>() { "a", "a", "b", "b", "r", "t" }; 

Làm thế nào tôi có thể nhận được chỉ "a", "b"?

Tôi cố gắng để làm như thế này:

List<string> list = new List<string>() { "a", "a", "b", "b", "r", "t" }; 
List<string> test_list = new List<string>(); 

test_list = list.Distinct().ToList(); 

Bây giờ test_list có { "a", "b", "r", "t"}
Và sau đó:

test_list = test_list.Except(list).ToList(); 

Vì vậy, đó là điểm thất bại của tôi, gây ra Ngoại trừ() đã xóa tất cả các yếu tố.

Bạn có thể giúp tôi giải pháp không?

+1

Hãy xem phương thức 'GroupBy'. – Oded

+0

Hành vi được mong đợi hoàn toàn. Ngoại trừ() ngoại trừ từ test_list tất cả các mục được tìm thấy trong danh sách. Bạn đang cố làm gì vậy? – Tommi

+0

bản sao có thể có của [Cách nhận các mục trùng lặp từ danh sách bằng LINQ?] (Http://stackoverflow.com/questions/3811464/how-to-get-duplicate-items-from-a-list-using-linq) –

Trả lời

9

Hãy thử điều này

var duplicates = list.GroupBy(a => a).SelectMany(ab => ab.Skip(1).Take(1)).ToList(); 
+6

Tôi không hiểu tại sao câu trả lời này được bỏ phiếu. Bất kỳ ai đã thử nó với '{" a "," a "," b "," b "," a "," r "," t "}'? – I4V

+0

Bạn _could_ làm điều đó. Thành thật mà nói, tôi đã phải suy nghĩ quá lâu và khó khăn về _why_ phương pháp này thực sự hoạt động. Tôi thích l4V hơn; dễ đọc hơn và dễ hiểu hơn. EDIT: Có lẽ nó nhanh hơn, nhưng tôi nghi ngờ hiệu suất là bất kỳ vấn đề ở tất cả trong trường hợp này. –

+1

I4V, bạn nói đúng, nó không hoạt động chính xác – Alex

0
var duplicates = list.GroupBy(s => s).SelectMany(g => g.Skip(1).Take(1)).ToList(); 
+0

Đây là phiên bản thứ nhất của câu trả lời [@ Sachin] (http://stackoverflow.com/a/15866810/200449), xem nhận xét và chỉnh sửa của nó –

+0

Đó là lựa chọn tốt nhất cho tôi. Tôi bỏ lỡ một điểm trong câu hỏi của tôi: nếu tôi có {a, a, a, b, b, r}, vì vậy ở đầu ra tôi sẽ nhận được {a, a, b} – Alex

3

Một phương pháp đơn giản là sử dụng Enumerable.GroupBy:

var dups = list.GroupBy(s => s) 
       .Where(g => g.Count() > 1) 
       .Select(g => g.Key); 
16
List<string> list = new List<string>() { "a", "a", "b", "b", "r", "t" }; 

var dups = list.GroupBy(x => x) 
    .Where(x => x.Count() > 1) 
    .Select(x => x.Key) 
    .ToList(); 
+2

Điều này dễ đọc hơn và dễ hiểu hơn, Cảm ơn –

0
var duplicates = list.GroupBy(a => a).SelectMany(ab => ab.Skip(1).Take(1)).ToList(); 

Nó sẽ hiệu quả hơn sau đó một trong những sử dụng Where(g => g.Count() > 1) và sẽ chỉ trả về một phần tử từ mỗi nhóm.

10
var list = new List<string> { "a", "a", "b", "b", "r", "t" }; 

var distinct = new HashSet<string>();  
var duplicates = new HashSet<string>(); 

foreach (var s in list) 
    if (!distinct.Add(s)) 
     duplicates.Add(s); 

// distinct == { "a", "b", "r", "t" } 
// duplicates == { "a", "b" } 
+2

+ 1 có lẽ là cách tiếp cận hiệu quả nhất. –

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