Adakah yang punya metode cepat untuk menghapus duplikat Daftar generik dalam C #?
c#
list
generics
duplicates
JC Grubbs
sumber
sumber
ICollection<MyClass> withoutDuplicates = new HashSet<MyClass>(inputList);
Jawaban:
Mungkin Anda harus mempertimbangkan menggunakan HashSet .
Dari tautan MSDN:
sumber
HashSet
tidak memiliki indeks , karena itu tidak selalu memungkinkan untuk menggunakannya. Saya harus membuat daftar besar sekali tanpa duplikat dan kemudian menggunakannya untukListView
dalam mode virtual. Itu sangat cepat untuk membuat yangHashSet<>
pertama dan kemudian mengubahnya menjadiList<>
(sehinggaListView
dapat mengakses item dengan indeks).List<>.Contains()
terlalu lambat.Jika Anda menggunakan .Net 3+, Anda dapat menggunakan Linq.
sumber
Bagaimana tentang:
Di .net 3.5?
sumber
Cukup inisialisasi HashSet dengan Daftar dengan tipe yang sama:
Atau, jika Anda ingin Daftar dikembalikan:
sumber
List<T>
menggunakan hasilnyanew HashSet<T>(withDupes).ToList()
Sortir, lalu centang dua dan dua di samping satu sama lain, karena duplikat akan mengumpul.
Sesuatu seperti ini:
Catatan:
sumber
RemoveAt
adalah operasi yang sangat mahal padaList
Saya suka menggunakan perintah ini:
Saya memiliki bidang ini dalam daftar saya: Id, StoreName, City, PostalCode. Saya ingin menampilkan daftar kota dalam dropdown yang memiliki nilai duplikat. solusi: Kelompokkan menurut kota lalu pilih yang pertama untuk daftar.
Saya harap ini membantu :)
sumber
Ini berhasil untuk saya. cukup gunakan
Ganti "Ketik" dengan jenis yang Anda inginkan misalnya int.
sumber
Seperti kata kronoz dalam .Net 3.5 Anda dapat menggunakan
Distinct()
.Di .Net 2 Anda bisa menirunya:
Ini dapat digunakan untuk menyimpulkan koleksi apa pun dan akan mengembalikan nilai dalam urutan asli.
Biasanya lebih cepat untuk memfilter koleksi (seperti keduanya
Distinct()
dan sampel ini) daripada menghapus item dari itu.sumber
HashSet
konstruktor terputus, yang membuatnya lebih baik untuk sebagian besar keadaan. Namun, ini akan mempertahankan urutan, yangHashSet
tidak.Dictionary<T, object>
gantinya, ganti.Contains
dengan.ContainsKey
dan.Add(item)
dengan.Add(item, null)
HashSet
mempertahankan pesanan sementaraDistinct()
tidak.Metode ekstensi mungkin cara yang layak untuk dilakukan ... sesuatu seperti ini:
Dan kemudian panggil seperti ini, misalnya:
sumber
Di Jawa (saya berasumsi C # kurang lebih identik):
Jika Anda benar-benar ingin mengubah daftar asli:
Untuk mempertahankan pesanan, cukup ganti HashSet dengan LinkedHashSet.
sumber
var noDupes = new HashSet<T>(list); list.Clear(); list.AddRange(noDupes);
:)Ini membutuhkan elemen yang berbeda (elemen tanpa elemen duplikat) dan mengubahnya menjadi daftar lagi:
sumber
Catatan: Solusi ini tidak memerlukan pengetahuan tentang Linq, selain itu ia ada.
Kode
Mulailah dengan menambahkan berikut ini ke bagian atas file kelas Anda:
Sekarang, Anda dapat menggunakan berikut untuk menghapus duplikat dari obyek disebut,
obj1
:Catatan: Ganti nama
obj1
menjadi nama objek Anda.Bagaimana itu bekerja
Perintah Union mencantumkan satu dari setiap entri dari dua objek sumber. Karena obj1 adalah kedua objek sumber, ini mengurangi obj1 ke salah satu dari setiap entri.
The
ToList()
mengembalikan Daftar baru. Ini diperlukan, karena perintah Linq sepertiUnion
mengembalikan hasil sebagai hasil IEnumerable alih-alih memodifikasi Daftar asli atau mengembalikan Daftar baru.sumber
Sebagai metode pembantu (tanpa Linq):
sumber
Jika Anda tidak peduli tentang pesanan Anda hanya bisa mendorong item ke dalam
HashSet
, jika Anda tidak ingin mempertahankan urutan Anda dapat melakukan sesuatu seperti ini:Atau cara Linq:
Edit: The
HashSet
metode adalahO(N)
waktu danO(N)
ruang sambil memilah dan kemudian membuat unik (seperti yang disarankan oleh @ lassevk dan lain-lain) adalahO(N*lgN)
waktu danO(1)
ruang sehingga tidak begitu jelas bagi saya (seperti pada pandangan pertama) bahwa cara menyortir lebih rendah (saya permintaan maaf untuk suara turun sementara ...)sumber
Berikut adalah metode ekstensi untuk menghapus duplikat yang berdekatan di tempat. Panggil Sortir () terlebih dahulu dan berikan IComparer yang sama. Ini harus lebih efisien daripada versi Lasse V. Karlsen yang memanggil RemoveAt berulang kali (menghasilkan beberapa blok memori bergerak).
sumber
Menginstal paket MoreLINQ melalui Nuget, Anda dapat dengan mudah membedakan daftar objek dengan properti
sumber
Mungkin lebih mudah untuk memastikan bahwa duplikat tidak ditambahkan ke daftar.
sumber
List<T>.Contains
metode ini setiap kali tetapi dengan lebih dari 1.000.000 entri. Proses ini memperlambat aplikasi saya. Saya menggunakan yangList<T>.Distinct().ToList<T>()
pertama sebagai gantinya.Anda bisa menggunakan Union
sumber
Cara lain di .Net 2.0
sumber
Ada banyak cara untuk menyelesaikan - masalah duplikat dalam Daftar, di bawah ini adalah salah satunya:
Ceria Ravi Ganesan
sumber
Berikut adalah solusi sederhana yang tidak memerlukan LINQ yang sulit dibaca atau penyortiran daftar sebelumnya.
sumber
Jawaban David J. adalah metode yang baik, tidak perlu objek tambahan, penyortiran, dll. Namun dapat diperbaiki:
for (int innerIndex = items.Count - 1; innerIndex > outerIndex ; innerIndex--)
Jadi loop luar berada di bagian bawah atas untuk seluruh daftar, tetapi loop bagian dalam pergi ke bawah "sampai posisi loop luar tercapai".
Loop luar memastikan seluruh daftar diproses, loop dalam menemukan duplikat yang sebenarnya, itu hanya dapat terjadi di bagian yang loop belum diproses.
Atau jika Anda tidak ingin melakukan bottom up untuk loop dalam, Anda bisa memulai loop dalam di luarIndex + 1.
sumber
Semua jawaban menyalin daftar, atau membuat daftar baru, atau menggunakan fungsi lambat, atau lambat sekali.
Menurut pemahaman saya, ini adalah metode tercepat dan termurah yang saya tahu (juga, didukung oleh seorang programmer yang sangat berpengalaman yang berspesialisasi pada optimasi fisika waktu nyata).
Biaya akhir adalah:
nlogn + n + nlogn = n + 2nlogn = O (nlogn) yang cukup bagus.
Catatan tentang RemoveRange: Karena kita tidak dapat menetapkan hitungan daftar dan menghindari menggunakan fungsi Hapus, saya tidak tahu persis kecepatan operasi ini, tetapi saya kira itu adalah cara tercepat.
sumber
Jika Anda memiliki kelas derek
Product
danCustomer
dan kami ingin menghapus item duplikat dari daftar merekaAnda harus mendefinisikan kelas generik dalam formulir di bawah ini
kemudian, Anda dapat menghapus item duplikat di daftar Anda.
kode ini menghapus item duplikat dengan
Id
jika Anda ingin menghapus item duplikat oleh properti lain, Anda dapat mengubah yangnameof(YourClass.DuplicateProperty)
samanameof(Customer.CustomerName)
lalu menghapus item duplikat olehCustomerName
Properti.sumber
sumber
Implementasi intuitif sederhana:
sumber