Saya menggunakan di Dictionary<string, int>
mana int
hitungan tombol.
Sekarang, saya perlu mengakses Kunci yang dimasukkan terakhir di dalam Kamus, tetapi saya tidak tahu namanya. Upaya nyata:
int LastCount = mydict[mydict.keys[mydict.keys.Count]];
tidak berfungsi, karena Dictionary.Keys
tidak mengimplementasikan [] -indexer.
Saya hanya ingin tahu apakah ada kelas serupa? Saya berpikir tentang menggunakan Stack, tetapi itu hanya menyimpan string. Saya sekarang dapat membuat struct saya sendiri dan kemudian menggunakan Stack<MyStruct>
, tapi saya ingin tahu apakah ada alternatif lain, pada dasarnya Kamus yang mengimplementasikan [] -indexer pada Tombol?
c#
.net
dictionary
Michael Stum
sumber
sumber
Jawaban:
Seperti @Falanwe tunjukkan dalam komentar, melakukan sesuatu seperti ini tidak benar :
Anda tidak harus bergantung pada urutan tombol dalam Kamus. Jika Anda perlu memesan, Anda harus menggunakan OrderedDictionary , seperti yang disarankan dalam jawaban ini . Jawaban lain di halaman ini juga menarik.
sumber
HashTable
System.Collections.ICollection 'tidak mengandung definisi untuk' ElementAt 'dan tidak ada metode ekstensi' ElementAt 'menerima argumen pertama dari tipe' System.Collections.ICollection 'dapat ditemukanElementAtOrDefault
versi untuk bekerja dengan versi tanpa pengecualian.Dictionary<TKey,TValue>
dokumentasi "Urutan kunci diDictionary<TKey, TValue>.KeyCollection
tidak ditentukan." Pesanan tidak ditentukan, Anda tidak memiliki cara untuk mengetahui pasti yang ada di posisi terakhir (mydict.Count -1
)Anda dapat menggunakan OrderedDictionary .
sumber
Kamus adalah Tabel Hash, jadi Anda tidak tahu urutan penyisipan!
Jika Anda ingin mengetahui kunci yang disisipkan terakhir, saya sarankan memperluas Kamus untuk menyertakan nilai LastKeyInserted.
Misalnya:
Anda akan mengalami masalah namun ketika Anda menggunakannya
.Remove()
untuk mengatasinya Anda harus menyimpan daftar kunci yang dimasukkan.sumber
Mengapa Anda tidak memperluas kelas kamus untuk menambahkan properti yang disisipkan kunci terakhir. Sesuatu seperti yang berikut ini mungkin?
sumber
Anda selalu bisa melakukan ini:
Tapi saya tidak akan merekomendasikannya. Tidak ada jaminan bahwa kunci yang dimasukkan terakhir akan berada di akhir array. Pemesanan untuk Kunci pada MSDN tidak ditentukan, dan dapat berubah. Dalam tes saya yang sangat singkat, tampaknya memang dalam urutan penyisipan, tetapi Anda akan lebih baik membangun pembukuan yang tepat seperti tumpukan - seperti yang Anda sarankan (meskipun saya tidak melihat kebutuhan struct berdasarkan pada Anda pernyataan lainnya) - atau cache variabel tunggal jika Anda hanya perlu mengetahui kunci terbaru.
sumber
Saya pikir Anda dapat melakukan sesuatu seperti ini, sintaks mungkin salah, belum pernah menggunakan C # untuk sementara waktu untuk mendapatkan item terakhir
atau gunakan Max daripada Terakhir untuk mendapatkan nilai maksimal, saya tidak tahu mana yang lebih cocok dengan kode Anda.
sumber
Saya setuju dengan bagian kedua dari jawaban Patrick. Bahkan jika dalam beberapa tes tampaknya menjaga urutan penyisipan, dokumentasi (dan perilaku normal untuk kamus dan hash) secara eksplisit menyatakan bahwa pemesanan tidak ditentukan.
Anda hanya meminta masalah tergantung pada urutan kunci. Tambahkan pembukuan Anda sendiri (seperti kata Patrick, hanya satu variabel untuk kunci terakhir yang ditambahkan) untuk memastikan. Juga, jangan tergoda dengan semua metode seperti Last dan Max pada kamus karena itu mungkin terkait dengan komparator kunci (saya tidak yakin tentang itu).
sumber
Jika Anda memutuskan untuk menggunakan kode berbahaya yang dapat rusak, fungsi ekstensi ini akan mengambil kunci dari yang
Dictionary<K,V>
sesuai dengan pengindeksan internalnya (yang untuk Mono dan .NET saat ini tampaknya berada dalam urutan yang sama seperti yang Anda dapatkan dengan menyebutkanKeys
properti tersebut ).Jauh lebih baik menggunakan Linq:,
dict.Keys.ElementAt(i)
tetapi fungsi itu akan beralih O (N); berikut ini adalah O (1) tetapi dengan penalti kinerja refleksi.sumber
Salah satu alternatif akan menjadi KeyedCollection jika kunci tersebut tertanam dalam nilai.
Cukup buat implementasi dasar di kelas tertutup untuk digunakan.
Jadi untuk mengganti
Dictionary<string, int>
(yang bukan contoh yang sangat baik karena tidak ada kunci yang jelas untuk int).sumber
Cara Anda mengucapkan pertanyaan itu membuat saya percaya bahwa int dalam Kamus berisi "posisi" item pada Kamus. Menilai dari pernyataan bahwa kunci tidak disimpan dalam urutan yang ditambahkan, jika ini benar, itu berarti bahwa kunci.Count (atau .Count - 1, jika Anda menggunakan berbasis nol) harus tetap selalu menjadi nomor kunci yang dimasukkan terakhir?
Jika itu benar, apakah ada alasan mengapa Anda tidak bisa menggunakan Kamus <int, string> sehingga Anda dapat menggunakan mydict [mydict.Keys.Count]?
sumber
Saya tidak tahu apakah ini akan berhasil karena saya cukup yakin bahwa kunci tidak disimpan dalam urutan yang ditambahkan, tetapi Anda bisa melemparkan KunciKoleksi ke Daftar dan kemudian mendapatkan kunci terakhir dalam daftar ... tetapi akan layak untuk dilihat.
Satu-satunya hal lain yang dapat saya pikirkan adalah untuk menyimpan kunci dalam daftar pencarian dan menambahkan kunci ke daftar sebelum Anda menambahkannya ke kamus ... itu tidak cantik.
sumber
Untuk memperluas posting Daniels dan komentarnya mengenai kunci tersebut, karena kunci tersebut tetap tertanam dalam nilai, Anda dapat menggunakan menggunakan
KeyValuePair<TKey, TValue>
sebagai nilai. Alasan utama untuk ini adalah bahwa, secara umum, Kunci tidak selalu dapat diturunkan langsung dari nilai.Maka akan terlihat seperti ini:
Untuk menggunakan ini seperti pada contoh sebelumnya, Anda harus:
sumber
Kamus mungkin tidak terlalu intuitif untuk menggunakan indeks untuk referensi tetapi, Anda dapat memiliki operasi serupa dengan array KeyValuePair :
ex.
KeyValuePair<string, string>[] filters;
sumber
Anda juga dapat menggunakan SortedList dan mitra Generiknya. Dua kelas ini dan dalam jawaban Andrew Peters disebutkan OrderedDictionary adalah kelas kamus di mana item dapat diakses dengan indeks (posisi) serta dengan kunci. Cara menggunakan kelas-kelas ini Anda dapat menemukan: Kelas SortedList , Kelas Generik SortedList .
sumber
Visual Studio UserVoice memberikan link ke implementasi OrderedDictionary generik oleh dotmore.
Tetapi jika Anda hanya perlu mendapatkan pasangan kunci / nilai berdasarkan indeks dan tidak perlu mendapatkan nilai dengan kunci, Anda dapat menggunakan satu trik sederhana. Deklarasikan beberapa kelas generik (saya menyebutnya ListArray) sebagai berikut:
Anda juga dapat mendeklarasikannya dengan konstruktor:
Misalnya, Anda membaca beberapa pasangan kunci / nilai dari file dan hanya ingin menyimpannya sesuai urutan pembacaannya agar nanti dengan indeks:
Seperti yang mungkin Anda perhatikan, Anda tidak harus hanya memasangkan kunci / nilai di ListArray Anda. Array item mungkin memiliki panjang berapa pun, seperti dalam array bergerigi.
sumber