2010-07-13 44 views
7

Tôi có một lớp đơn giản biểu diễn một đối tượng. Nó có 5 thuộc tính (một ngày, 2 số thập phân, một số nguyên và một chuỗi). Tôi có một lớp sưu tập, có nguồn gốc từ CollectionBase, là một lớp chứa để chứa nhiều đối tượng từ lớp đầu tiên của tôi.Làm thế nào để tìm và loại bỏ các đối tượng trùng lặp trong một bộ sưu tập bằng LINQ?

Câu hỏi của tôi là, tôi muốn xóa các đối tượng trùng lặp (ví dụ: các đối tượng có cùng ngày, cùng số thập phân, cùng số nguyên và cùng một chuỗi). Có một truy vấn LINQ tôi có thể viết để tìm và loại bỏ các bản sao? Hoặc tìm thấy chúng ít nhất?

Trả lời

10

Bạn có thể xóa các từ khóa trùng lặp bằng cách sử dụng toán tử Distinct.

Có hai quá tải - một sử dụng trình so sánh bình đẳng mặc định cho loại của bạn (đối với loại tùy chỉnh sẽ gọi phương thức Equals() trên loại). Thứ hai cho phép bạn cung cấp bộ so sánh bình đẳng của riêng bạn. Cả hai đều trả về một chuỗi mới đại diện cho tập hợp ban đầu của bạn mà không trùng lặp. Cả quá tải không thực sự thay đổi bộ sưu tập ban đầu của bạn - chúng đều trả về một chuỗi mới không bao gồm các bản sao..

Nếu bạn muốn chỉ cần tìm các bản sao, bạn có thể sử dụng GroupBy để làm như vậy:

var groupsWithDups = list.GroupBy(x => new { A = x.A, B = x.B, ... }, x => x) 
         .Where(g => g.Count() > 1); 

Để loại bỏ bản sao từ một cái gì đó giống như một IList<> bạn có thể làm:

yourList.RemoveAll(yourList.Except(yourList.Distinct())); 
+0

Điều này sẽ xóa chúng khỏi bộ sưu tập của tôi hoặc chỉ từ Truy vấn LINQ? – Icemanind

+0

Phương thức mở rộng LINQ tạo bộ mặt hàng mới, bộ sưu tập ban đầu của bạn sẽ không bị ảnh hưởng. –

+0

Cảm ơn tất cả thông tin! – Icemanind

4

Nếu bạn đơn giản lớp sử dụng Equals theo cách thỏa mãn các yêu cầu của bạn, sau đó bạn có thể sử dụng phương pháp Riêng biệt

var col = ...; 
var noDupes = col.Distinct(); 

Nếu không, bạn sẽ cần cung cấp một phiên bản IEqualityComparer<T> so sánh các giá trị theo cách bạn muốn. Ví dụ (vấn đề vô bỏ qua cho ngắn gọn)

public class MyTypeComparer : IEqualityComparer<MyType> { 
    public bool Equals(MyType left, MyType right) { 
    return left.Name == right.Name; 
    } 
    public int GetHashCode(MyType type) { 
    return 42; 
    } 
} 

var noDupes = col.Distinct(new MyTypeComparer()); 

Lưu ý việc sử dụng một hằng số cho GetHashCode là cố ý. Nếu không biết chi tiết thân mật về ngữ nghĩa của MyType thì không thể viết hàm băm hiệu quả và chính xác. Thay cho hàm băm hiệu quả, tôi đã sử dụng một hằng số đúng bất kể ngữ nghĩa của kiểu.

+0

Điều này sẽ xóa chúng khỏi bộ sưu tập của tôi? Hoặc chỉ truy vấn LINQ? – Icemanind

+0

@icemanind nó sẽ trả về bộ sưu tập mới không có bản sao. Nó sẽ không sửa đổi một bộ sưu tập tại chỗ. – JaredPar

+1

Câu trả lời tuyệt vời và thực hành tốt nhất – danielea

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