Cara menggabungkan 2 Daftar <T> dan menghapus nilai duplikat dari dalam C #


159

Saya memiliki dua daftar Daftar yang perlu saya gabungkan di daftar ketiga dan menghapus nilai duplikat dari daftar itu

Agak sulit dijelaskan, jadi izinkan saya menunjukkan contoh seperti apa kode itu dan apa yang saya inginkan sebagai hasilnya, dalam sampel saya menggunakan tipe int bukan kelas ResultAnalysisFileSql.

first_list = [1, 12, 12, 5]

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

Hasil dari penggabungan dua daftar harus menghasilkan daftar ini: result_list = [1, 12, 5, 7, 9]

Anda akan melihat bahwa hasilnya memiliki daftar pertama, termasuk dua nilai "12", dan di second_list memiliki nilai tambahan 12, 1 dan 5.

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


    }

Adakah kode sampel untuk menggabungkan dan menghapus duplikat?

Jawaban:


288

Apakah Anda sudah melihat Enumerable.Union

Metode ini mengecualikan duplikat dari set kembali . Ini adalah perilaku yang berbeda dengan metode Concat, yang mengembalikan semua elemen dalam urutan input termasuk duplikat.

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: Apakah kelas Anda mengimplementasikan IEqualityComparer <T>? Jika demikian, Anda harus memeriksa metode GetHashCode dan Equals Anda. Lihat bagian Keterangan pada msdn.microsoft.com/en-us/library/bb341731.aspx .
Tomas Narros

1
Penting untuk dicatat karena saya mengalami masalah dalam menggunakan ini pada 2 koleksi berbeda: "Anda tidak dapat menyatukan dua jenis yang berbeda, kecuali satu mewarisi dari yang lain" dari stackoverflow.com/a/6884940/410937 yang menghasilkan cannot be inferred from the usagekesalahan.
atconway

30

mengapa tidak misalnya saja

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

oh ... menurut msdn Anda dapat meninggalkan.Distinct()

Metode ini mengecualikan duplikat dari set kembali


25

Union tidak memiliki kinerja yang baik: artikel ini menjelaskan tentang membandingkannya dengan satu sama lain

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

Daftar dan penggabungan LINQ: 4820 ms
Penggabungan kamus: 16ms
HashSet dan IEqualityComparer: 20ms
LINQ Union dan IEqualityComparer: 24ms


1
Juga manfaat lain menggunakan gabungan kamus -> Saya punya dua daftar yang kembali dari data DB. Dan data saya memiliki bidang stempel waktu, yang berbeda dalam dua daftar data. Dengan serikat saya mendapatkan duplikat karena stempel waktu berbeda. Tetapi dengan penggabungan, saya dapat memutuskan bidang unik mana yang ingin saya pertimbangkan dalam kamus. +1
JimSan

Dapat bervariasi tergantung kecepatan prosesor, tergantung jenis CPU yang Anda miliki.
Asad Ali

7
Dan di akhir artikel itu tertulis, "Saya lebih suka LINQ Union karena itu menyampaikan maksud dengan sangat jelas." ;) (juga, hanya ada perbedaan 8 ms)
James Wilkins

1
Untuk daftar kecil yang perbedaannya dapat diabaikan, Unionmenghasilkan kode yang lebih bersih dan lebih mudah dibaca. Menghabiskan waktu untuk hiper-optimisasi kode ketika tidak lambat dapat dikenakan penalti pemeliharaan di jalan.
elolos

14

Gunakan Linq's Union:

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);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.