2010-10-27 25 views
107

Tôi có Liệt kê hai danh sách mà tôi cần phải kết hợp và loại bỏ các giá trị nhân bản của cả hai danh sáchlàm thế nào để hợp nhất 2 Danh sách <T> với loại bỏ giá trị trùng lặp trong C#

Một chút khó khăn để giải thích, vì vậy hãy để tôi chỉ cho một ví dụ về những gì mã trông giống như, và những gì tôi muốn như một kết quả, trong mẫu tôi sử dụng loại int không ResultAnalysisFileSql lớp.

first_list = [1, 12, 12, 5]

second_list = [12, 5, 7, 9, 1]

Kết quả của việc kết hợp hai danh sách nên kết quả trong danh sách này: results_list = [1, 12, 5, 7, 9]

Bạn sẽ nhận thấy kết quả có danh sách đầu tiên, bao gồm hai giá trị "12" và trong second_list có giá trị 12, 1 và 5 bổ sung.

lớp ResultAnalysisFileSql

[Serializable] 
    public partial class ResultAnalysisFileSql 
    { 
     public string FileSql { get; set; } 

     public string PathFileSql { get; set; } 

     public List<ErrorAnalysisSql> Errors { get; set; } 

     public List<WarningAnalysisSql> Warnings{ get; set; } 

     public ResultAnalysisFileSql() 
     { 

     } 

     public ResultAnalysisFileSql(string fileSql) 
     { 
      if (string.IsNullOrEmpty(fileSql) 
       || fileSql.Trim().Length == 0) 
      { 
       throw new ArgumentNullException("fileSql", "fileSql is null"); 
      } 

      if (!fileSql.EndsWith(Utility.ExtensionFicherosErrorYWarning)) 
      { 
       throw new ArgumentOutOfRangeException("fileSql", "Ruta de fichero Sql no tiene extensión " + Utility.ExtensionFicherosErrorYWarning); 
      } 

      PathFileSql = fileSql; 
      FileSql = ObtenerNombreFicheroSql(fileSql); 
      Errors = new List<ErrorAnalysisSql>(); 
      Warnings= new List<WarningAnalysisSql>(); 
     } 

     private string ObtenerNombreFicheroSql(string fileSql) 
     { 
      var f = Path.GetFileName(fileSql); 
      return f.Substring(0, f.IndexOf(Utility.ExtensionFicherosErrorYWarning)); 
     } 


     public override bool Equals(object obj) 
     { 
      if (obj == null) 
       return false; 
      if (!(obj is ResultAnalysisFileSql)) 
       return false; 

      var t = obj as ResultAnalysisFileSql; 
      return t.FileSql== this.FileSql 
       && t.PathFileSql == this.PathFileSql 
       && t.Errors.Count == this.Errors.Count 
       && t.Warnings.Count == this.Warnings.Count; 
     } 


    } 

Bất kỳ mẫu mã cho máy liên hợp và loại bỏ các bản sao không?

Trả lời

203

Quý vị có một cái nhìn tại Enumerable.Union

Phương pháp này không bao gồm bản sao từ sự trở lại thiết lập. Điều này khác với hành vi đối với phương thức Concat , trả về tất cả các phần tử trong các chuỗi đầu vào bao gồm các bản sao.

List<int> list1 = new List<int> { 1, 12, 12, 5}; 
List<int> list2 = new List<int> { 12, 5, 7, 9, 1 }; 
List<int> ulist = list1.Union(list2).ToList(); 
+1

khi tôi sử dụng 'Bộ sưu tập ' không hoạt động và chỉ chuyển tất cả các mục ... –

+5

@Dr TJ: Lớp học của bạn có triển khai IEqualityComparer không? Nếu vậy, bạn sẽ cần phải kiểm tra các phương thức GetHashCode và Equals của bạn. Xem phần Nhận xét của http://msdn.microsoft.com/en-us/library/bb341731.aspx. –

+1

Quan trọng cần lưu ý vì tôi gặp phải sự cố khi sử dụng tính năng này trên 2 bộ sưu tập khác nhau: "Bạn không thể kết hợp hai loại khác nhau, trừ khi một người khác kế thừa từ" khác từ http://stackoverflow.com/a/6884940/410937 mang lại 'không thể suy ra từ lỗi usage'. – atconway

22

tại sao không chỉ đơn giản là ví dụ

var newList = list1.Union(list2)/*.Distinct()*//*.ToList()*/; 

oh ... theo msdn bạn có thể bỏ qua .Distinct()

Phương pháp này không bao gồm bản sao từ sự trở lại thiết lập

12

Liên minh Sử dụng LINQ của:

using System.Linq; 
var l1 = new List<int>() { 1,2,3,4,5 }; 
var l2 = new List<int>() { 3,5,6,7,8 }; 
var l3 = l1.Union(l2).ToList(); 
10
List<int> first_list = new List<int>() { 
     1, 
     12, 
     12, 
     5 
    }; 

    List<int> second_list = new List<int>() { 
     12, 
     5, 
     7, 
     9, 
     1 
    }; 

    var result = first_list.Union(second_list); 
+1

Bạn không cần phải gọi riêng biệt, hãy đọc tài liệu http://msdn.microsoft.com/en-us/library/bb341731.aspx hoặc tự mình thử nghiệm ... –

16

Liên minh có hiệu quả không tốt: đây article mô tả về so sánh chúng với nhau

var dict = list2.ToDictionary(p => p.Number); 
foreach (var person in list1) 
{ 
     dict[person.Number] = person; 
} 
var merged = dict.Values.ToList(); 

Lists và LINQ hợp nhất: 4820ms
điển merge: 16ms
HashSet và IEqualityComparer: 20ms
LINQ Union và IEqualityComparer: 24ms

+0

Ngoài ra một lợi ích khác của việc sử dụng kết hợp từ điển - > Tôi có hai danh sách quay trở lại từ dữ liệu DB. Và dữ liệu của tôi có trường dấu thời gian, trường này khác nhau trong hai danh sách dữ liệu. Với công đoàn tôi nhận được bản sao do dấu thời gian là khác nhau. Nhưng với việc hợp nhất, tôi có thể quyết định trường nào tôi muốn xem xét trong từ điển. +1 – JimSan

+0

Có thể thay đổi tùy theo tốc độ xử lý, phụ thuộc vào loại CPU bạn có. –

+2

Và ở cuối bài báo, nó nói, "Tôi thích LINQ Union vì nó truyền đạt ý định rất rõ ràng." ;) (cũng có, chỉ có một sự khác biệt 8 ms) –

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