Cách hợp nhất 2 Danh sách <T> và xóa các giá trị trùng lặp khỏi nó trong C #


158

Tôi có hai danh sách Danh sách mà tôi cần kết hợp trong danh sách thứ ba và xóa các giá trị trùng lặp khỏi danh sách đó

Hơi khó để giải thích, vì vậy hãy để tôi đưa ra một ví dụ về mã trông như thế nào và kết quả tôi muốn là gì, trong mẫu tôi sử dụng kiểu int không phải là lớp resultAnalysisFileSql.

danh sách đầu tiên = [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 sẽ dẫn đến danh sách này: result_list = [1, 12, 5, 7, 9]

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

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ã mẫu để kết hợp và loại bỏ trùng lặp?

Câu trả lời:


287

Bạn đã có một cái nhìn tại En đếmable.Union

Phương pháp này không bao gồm các bản sao từ bộ trả về . Đây là hành vi khác với phương thức Concat, trả về tất cả các phần tử trong chuỗi đầu vào bao gồm cả 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();

// ulist output : 1, 12, 5, 7, 9

6
@Dr TJ: Lớp người của bạn có triển khai IEqualityComparer <T> không? Nếu vậy, bạn sẽ cần kiểm tra các phương thức GetHashCode và Equals của mình. Xem phần Ghi chú của msdn.microsoft.com/en-us/l Library / bb341731.aspx .
Tomas Narros

1
Điều quan trọng cần lưu ý bởi vì tôi gặp phải các vấn đề khi sử dụng điều 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 loại kế thừa từ loại kia" từ stackoverflow.com/a/6884940/410937 dẫn đến cannot be inferred from the usagelỗi.
atconway

30

tại sao không đơn giản là vd

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

oh ... theo msd bạn có thể rời khỏi.Distinct()

Phương pháp này loại trừ trùng lặp từ bộ trả về


25

Liên minh có hiệu suất không tốt: bài viết này mô tả về việc 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();

Hợp nhất danh sách và LINQ: Hợp
nhất từ ​​điển 4820ms : 16ms Hashset
và IEqualityComparer: 20ms
LINQ Union và IEqualityComparer: 24ms


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

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

7
Và ở phần cuối của bài báo có đoạn: "Tôi thích LINQ Union vì nó truyền đạt ý định rất rõ ràng." ;) (cũng vậy, chỉ có chênh lệch 8 ms)
James Wilkins

1
Đối với các danh sách nhỏ có sự khác biệt không đáng kể, Unionkết quả là mã sạch hơn và dễ đọc hơn. Dành thời gian để siêu tối ưu hóa mã khi nó không chậm có thể phải chịu một hình phạt bảo trì xuống đường.
elolos

14

Sử dụng Liên minh Linq:

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();

11
    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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.