Lebih
Cara terbaik untuk menghapus item dari koleksi
Apa cara terbaik untuk pendekatan menghapus item dari koleksi di C#, setelah item dikenal, tapi bukan itu's indeks. Ini adalah salah satu cara untuk melakukan hal itu, tetapi tampaknya janggal di terbaik.
//Remove the existing role assignment for the user.
int cnt = 0;
int assToDelete = 0;
foreach (SPRoleAssignment spAssignment in workspace.RoleAssignments)
{
if (spAssignment.Member.Name == shortName)
{
assToDelete = cnt;
}
cnt++;
}
workspace.RoleAssignments.Remove(assToDelete);
Apa yang saya benar-benar ingin lakukan adalah menemukan item untuk menghapus dengan properti (dalam hal ini, nama) tanpa perulangan melalui seluruh koleksi dan menggunakan 2 variabel tambahan.
69
14
Jika RoleAssignments adalah
Daftar<T>
anda dapat menggunakan kode berikut.Jika anda ingin mengakses anggota dari koleksi oleh salah satu sifat mereka, anda mungkin mempertimbangkan menggunakan
Kamus<T>
atauKeyedCollection<T>
sebagai gantinya. Dengan cara ini anda don't harus mencari item yang anda're looking for.Jika tidak, anda setidaknya bisa melakukan hal ini:
@smaclell bertanya mengapa reverse iterasi lebih efisien di dalam komentar untuk @sambo99.
Sometimes itu's lebih efisien. Anggap anda memiliki daftar orang-orang, dan anda ingin menghilangkan atau menyaring semua pelanggan dengan peringkat kredit < 1000;
Kami memiliki data sebagai berikut
Jika kita beralih ke depan, kita'd segera mendapatkan masalah
Di idx = 0 kami menghapus
Bob
, yang kemudian menggeser semua elemen yang tersisa kiri. Waktu berikutnya melalui loop idx = 1, tapi daftar[1] sekarangTed
bukanMaria
. Kami akhirnya melewatiMaria
oleh kesalahan. Kita bisa menggunakan while loop, dan kita bisa memperkenalkan lebih variabel.Atau, kita hanya membalikkan iterate:
Semua indeks ke kiri dari item yang dihapus tetap sama, sehingga anda don't lewatkan setiap item.
Prinsip yang sama berlaku jika anda're diberikan daftar indeks untuk menghapus dari array. Dalam rangka untuk menjaga hal-hal lurus yang anda butuhkan untuk mengurutkan daftar dan kemudian menghapus item dari index tertinggi sampai yang terendah.
Sekarang anda hanya dapat menggunakan Linq dan menyatakan apa yang anda're lakukan dengan cara yang sederhana.
Untuk kasus ini menghapus satu item,'s tidak ada yang lebih efisien iterasi ke depan atau ke belakang. Anda juga bisa menggunakan Linq untuk ini.
Untuk Daftar sederhana struktur cara yang paling efisien tampaknya akan menggunakan Predikat RemoveAll implementasi.
Misalnya.
Alasan:
Jika anda terjebak menerapkan ini dalam pra c# 3.0 era. Anda memiliki 2 pilihan.
Misalnya.
Atau
Jika anda menghapus hal-hal yang benar-benar sering dari daftar, mungkin struktur lain seperti HashTable (.net 1.1) atau Kamus (.net 2.0) atau HashSet (.net 3.5) yang lebih cocok untuk tujuan ini.
Jika itu's
ICollection
maka anda tidak't memilikiRemoveAll
metode. Berikut ini's sebuah metode penyuluhan yang akan melakukannya:Berdasarkan pada: http://phejndorf.wordpress.com/2011/03/09/a-removeall-extension-for-the-collection-class/
Apa jenis koleksi? Jika itu's Daftar, anda bisa gunakan membantu "RemoveAll":
(Ini bekerja di .NET 2.0. Tentu saja, jika anda don't memiliki baru compiler, anda'll harus menggunakan "mendelegasikan (SPRoleAssignment spa) { return spa.Anggota.Nama == shortName; " bukannya bagus lambda sintaks.)
Pendekatan lain jika itu's tidak Daftar, tapi masih ICollection:
Ini membutuhkan Enumerable metode ekstensi. (Anda dapat menyalin Mono yang dalam, jika anda terjebak di .NET 2.0). Jika itu's beberapa koleksi kustom yang tidak bisa mengambil item, tapi HARUS mengambil sebuah indeks, beberapa lainnya Enumerable metode, seperti Select, lulus dalam indeks integer untuk anda.
Berikut ini adalah cara yang cukup baik untuk melakukan itu
http://support.microsoft.com/kb/555972
Ini adalah solusi generik
Itu akan terlihat jauh lebih sederhana jika metode ekstensi dukungan lewat referensi ! penggunaan:
EDIT: memastikan bahwa daftar perulangan tetap berlaku bahkan ketika menghapus item dengan decrementing index (bei).
Cara terbaik untuk melakukannya adalah dengan menggunakan linq.
Contoh kelas:
Linq query:
Query ini akan menghapus semua elemen dari
collection1
jikaNama
pertandingan setiap elemenNama
daricollection2
Ingat untuk menggunakan:
menggunakan Sistem.Linq;
Untuk melakukan hal ini sementara perulangan melalui pengumpulan dan tidak mendapatkan memodifikasi koleksi pengecualian, ini adalah pendekatan yang saya'telah diambil di masa lalu (perhatikan .Kedaftar() pada akhir dari koleksi asli, hal ini menciptakan koleksi lain dalam memori, maka anda dapat memodifikasi koleksi yang ada)
Ada pendekatan lain yang dapat anda ambil tergantung pada bagaimana anda're menggunakan koleksi anda. Jika anda're men-download tugas satu waktu (misalnya, ketika aplikasi berjalan), anda bisa menerjemahkan koleksi terbang ke hashtable dimana:
shortname => SPRoleAssignment
Jika anda melakukan ini, maka ketika anda ingin menghapus item dengan nama pendek, semua yang perlu anda lakukan adalah menghapus item dari hashtable oleh kunci.
Sayangnya, jika anda're loading ini SPRoleAssignments banyak, yang jelas isn't akan ada biaya yang lebih efisien dalam hal waktu. Saran-saran orang lain tentang menggunakan Linq akan lebih baik jika anda'kembali menggunakan versi baru .NET Framework, tapi jika tidak, anda'll harus tetap berpegang pada metode anda're menggunakan.
Serupa dengan Kamus Pengumpulan point of view, yang telah saya lakukan ini.
Catatan: Kode di atas akan gagal dalam .Net Profil Klien (3.5 dan 4.5) juga beberapa penonton yang disebutkan itu adalah Gagal untuk mereka .Net4.0 juga tidak yakin setelan mana yang menyebabkan masalah.
Jadi ganti dengan kode di bawah ini (.Kedaftar()) Dimana pernyataan, untuk menghindari kesalahan itu. "Koleksi dimodifikasi; pencacahan operasi mungkin tidak dapat mengeksekusi."
Per MSDN Dari .Net4.5 dan seterusnya Profil Klien dihentikan. http://msdn.microsoft.com/en-us/library/cc656912(v=vs. 110).aspx
Menyimpan barang-barang anda terlebih dahulu, dari menghapusnya.
Anda perlu mengganti
GetHashCode()
di kelas Item.Banyak respon yang baik di sini, saya sangat suka ekspresi lambda...sangat bersih. Aku lalai, bagaimanapun, tidak menentukan jenis Koleksi. Ini adalah SPRoleAssignmentCollection (dari LUMUT) yang hanya telah Menghapus(int) dan Menghapus(SPPrincipal), tidak berguna RemoveAll(). Jadi, saya telah menetap ini, kecuali ada saran yang lebih baik.