Saya mencoba membuat diagram lingkaran dari kamus. Sebelum saya menampilkan diagram lingkaran, saya ingin merapikan datanya. Saya menghapus setiap irisan pai yang kurang dari 5% dari pai dan menempatkannya dalam irisan pai "Lainnya". Namun saya mendapatkan Collection was modified; enumeration operation may not execute
pengecualian saat runtime.
Saya mengerti mengapa Anda tidak dapat menambah atau menghapus item dari kamus saat iterasi. Namun saya tidak mengerti mengapa Anda tidak bisa begitu saja mengubah nilai untuk kunci yang ada dalam loop foreach.
Setiap saran ulang: memperbaiki kode saya, akan dihargai.
Dictionary<string, int> colStates = new Dictionary<string,int>();
// ...
// Some code to populate colStates dictionary
// ...
int OtherCount = 0;
foreach(string key in colStates.Keys)
{
double Percent = colStates[key] / TotalCount;
if (Percent < 0.05)
{
OtherCount += colStates[key];
colStates[key] = 0;
}
}
colStates.Add("Other", OtherCount);
Panggil
ToList()
di dalamforeach
loop. Dengan cara ini kita tidak memerlukan salinan variabel temp. Itu tergantung pada Linq yang tersedia sejak. Net 3.5.sumber
foreach(var pair in colStates.ToList())
untuk menghindari memiliki akses ke Kunci dan Nilai yang menghindari harus memanggilcolStates[key]
..Anda mengubah koleksi di baris ini:
Dengan melakukannya, Anda pada dasarnya menghapus dan memasukkan kembali sesuatu pada titik itu (sejauh menyangkut IEnumerable.
Jika Anda mengedit anggota dari nilai yang Anda simpan, itu akan baik-baik saja, tetapi Anda mengedit nilai itu sendiri dan IEnumberable tidak menyukainya.
Solusi yang saya gunakan adalah menghilangkan foreach loop dan cukup gunakan for loop. Simpul untuk loop tidak akan memeriksa perubahan yang Anda tahu tidak akan memengaruhi koleksi.
Inilah cara Anda dapat melakukannya:
sumber
colStates.Keys
di tempatkeys
.Anda tidak dapat mengubah kunci atau nilai-nilai secara langsung dalam ForEach, tetapi Anda dapat memodifikasi anggota mereka. Misalnya, ini seharusnya bekerja:
sumber
Bagaimana kalau hanya melakukan beberapa permintaan LINQ terhadap kamus Anda, dan kemudian mengikat grafik Anda ke hasil dari mereka? ...
sumber
Jika Anda merasa kreatif, Anda bisa melakukan sesuatu seperti ini. Ulangi kamus untuk melakukan perubahan.
Tentu saja tidak identik, tetapi Anda mungkin tertarik ...
sumber
Anda perlu membuat Kamus baru dari yang lama alih-alih memodifikasi di tempat. Sesuatu seperti (juga beralih pada KeyValuePair <,> daripada menggunakan pencarian kunci:
sumber
Dimulai dengan .NET 4.5 Anda dapat melakukan ini dengan ConcurrentDictionary :
Namun perlu dicatat bahwa kinerjanya sebenarnya jauh lebih buruk daripada yang sederhana
foreach dictionary.Kes.ToArray()
:Hasil:
sumber
Anda tidak dapat mengubah koleksi, bahkan nilainya. Anda dapat menyimpan kasus-kasus ini dan menghapusnya nanti. Itu akan berakhir seperti ini:
sumber
Penafian: Saya tidak berbuat banyak C #
Anda mencoba untuk memodifikasi objek DictionaryEntry yang disimpan di HashTable. Hashtable hanya menyimpan satu objek - instance Anda dari DictionaryEntry. Mengubah Kunci atau Nilai sudah cukup untuk mengubah HashTable dan menyebabkan enumerator menjadi tidak valid.
Anda dapat melakukannya di luar loop:
dengan terlebih dahulu membuat daftar semua kunci dari nilai yang ingin Anda ubah dan beralih melalui daftar itu.
sumber
Anda dapat membuat daftar salinan
dict.Values
, kemudian Anda dapat menggunakanList.ForEach
fungsi lambda untuk iterasi, (atauforeach
loop, seperti yang disarankan sebelumnya).sumber
Bersamaan dengan jawaban yang lain, saya pikir saya akan perhatikan bahwa jika Anda mendapatkan
sortedDictionary.Keys
atausortedDictionary.Values
kemudian mengulanginyaforeach
, Anda juga harus mengurutkannya. Ini karena metode tersebut mengembalikanSystem.Collections.Generic.SortedDictionary<TKey,TValue>.KeyCollection
atauSortedDictionary<TKey,TValue>.ValueCollection
objek, yang mempertahankan semacam kamus asli.sumber
Jawaban ini untuk membandingkan dua solusi, bukan solusi yang disarankan.
Alih-alih membuat daftar lain seperti jawaban yang disarankan, Anda dapat menggunakan
for
loop menggunakan kamusCount
untuk kondisi stop loop danKeys.ElementAt(i)
untuk mendapatkan kunci.Pada awalnya saya pikir ini akan lebih efisien karena kita tidak perlu membuat daftar kunci. Setelah menjalankan tes saya menemukan bahwa
for
solusi loop jauh lebih efisien. Alasannya adalah karenaElementAt
O (n) padadictionary.Keys
properti, ia mencari dari awal koleksi hingga sampai ke item ke-n.Uji:
Hasil:
sumber