Sangat mudah untuk mendapatkan nilai kunci dari Kamus umum .NET:
Dictionary<int, string> greek = new Dictionary<int, string>();
greek.Add(1, "Alpha");
greek.Add(2, "Beta");
string secondGreek = greek[2]; // Beta
Tetapi mencoba mendapatkan kunci yang diberi nilai tidak semudah itu karena mungkin ada beberapa kunci:
int[] betaKeys = greek.WhatDoIPutHere("Beta"); // expecting single 2
int[]
ketika Anda mengharapkan nilai tunggal?Jawaban:
Oke, inilah beberapa versi dua arah:
sumber
Seperti yang dikatakan orang lain, tidak ada pemetaan dalam kamus dari nilai ke kunci.
Saya baru saja memperhatikan Anda ingin memetakan dari nilai ke beberapa kunci - Saya meninggalkan solusi ini di sini untuk versi nilai tunggal, tetapi kemudian saya akan menambahkan jawaban lain untuk peta dua arah multi-entri.
Pendekatan normal yang dilakukan di sini adalah memiliki dua kamus - satu pemetaan dengan satu cara dan satu di lainnya. Enkapsulasi mereka dalam kelas yang terpisah, dan kerjakan apa yang ingin Anda lakukan ketika Anda memiliki kunci atau nilai duplikat (misalnya, membuat pengecualian, menimpa entri yang ada, atau mengabaikan entri baru). Secara pribadi, saya mungkin akan mengajukan pengecualian - ini membuat perilaku sukses lebih mudah untuk didefinisikan. Sesuatu seperti ini:
sumber
Add
panggilan kamus akan gagal - tetapi jika panggilan kamus yang kedua, kami kemudian membuat sistem menjadi bingung. Dengan cara saya, Anda masih memiliki koleksi yang konsisten setelah pengecualian.Kamus tidak benar-benar dimaksudkan untuk berfungsi seperti ini, karena meskipun keunikan kunci dijamin, keunikan nilai tidak. Jadi misalnya jika Anda punya
Apa yang ingin Anda dapatkan
greek.WhatDoIPutHere("Alpha")
?Oleh karena itu Anda tidak dapat mengharapkan sesuatu seperti ini untuk dimasukkan ke dalam kerangka kerja. Anda akan membutuhkan metode Anda sendiri untuk penggunaan unik Anda sendiri --- apakah Anda ingin mengembalikan array (atau
IEnumerable<T>
)? Apakah Anda ingin membuat pengecualian jika ada beberapa kunci dengan nilai yang diberikan? Bagaimana jika tidak ada?Secara pribadi saya akan mencari yang dapat dihitung, seperti:
sumber
Mungkin cara termudah untuk melakukannya, tanpa Linq, bisa dengan mengulang pasangan:
Jika Anda memiliki Linq, Anda dapat melakukannya dengan mudah seperti ini:
sumber
var
adalah fitur bahasa, bukan fitur kerangka kerja. Anda dapat menggunakan penggabungan-nol dari C # -6.0 dan tetap menargetkan CF-2.0 jika Anda benar-benar menginginkannya.Kamus tidak menyimpan hash nilai, hanya kuncinya, jadi penelusuran apa pun menggunakan nilai akan memakan waktu setidaknya linier. Taruhan terbaik Anda adalah dengan hanya mengulang elemen dalam kamus dan melacak kunci yang cocok atau beralih ke struktur data yang berbeda, mungkin mempertahankan dua kunci pemetaan kamus-> nilai dan nilai-> List_of_keys. Jika Anda melakukan yang terakhir, Anda akan menukar penyimpanan untuk kecepatan pencarian. Tidak perlu banyak untuk mengubah contoh @Cybis menjadi struktur data seperti itu.
sumber
Karena saya menginginkan Kamus BiDirectional yang lengkap (dan bukan hanya Peta), saya menambahkan fungsi yang hilang untuk menjadikannya kelas yang kompatibel dengan IDictionary. Ini didasarkan pada versi dengan Key-Value Pairs yang unik. Berikut file jika diinginkan (Sebagian besar pekerjaan adalah XMLDoc melalui):
sumber
direvisi: oke untuk memiliki beberapa jenis menemukan Anda akan memerlukan sesuatu selain kamus, karena jika Anda memikirkannya kamus adalah kunci satu arah. artinya, nilainya mungkin tidak unik
yang mengatakan sepertinya Anda menggunakan c # 3.0 sehingga Anda mungkin tidak perlu menggunakan perulangan dan dapat menggunakan sesuatu seperti:
sumber
Kelas kamus tidak dioptimalkan untuk kasus ini, tetapi jika Anda benar-benar ingin melakukannya (dalam C # 2.0), Anda dapat melakukan:
Saya lebih suka solusi LINQ untuk keanggunan, tetapi ini adalah cara 2.0.
sumber
Tidak dapatkah Anda membuat subkelas Kamus yang memiliki fungsi itu?
EDIT: Maaf, pertama kali tidak mendapatkan kode dengan benar.
sumber
Solusi kamus dua arah "sederhana" yang diusulkan di sini rumit dan mungkin sulit untuk dipahami, dipertahankan, atau diperluas. Juga pertanyaan asli meminta "kunci untuk sebuah nilai", tetapi jelas mungkin ada beberapa kunci (saya sudah mengedit pertanyaan itu). Seluruh pendekatan agak mencurigakan.
Perubahan perangkat lunak. Menulis kode yang mudah dipelihara harus diprioritaskan pada solusi kompleks "pintar" lainnya. Cara untuk mendapatkan kembali kunci dari nilai dalam kamus adalah dengan melakukan perulangan. Kamus tidak dirancang untuk dua arah.
sumber
int
nilai perstring
kunci, maka kamus dapat didefinisikan seperti ini:Dictionary<string, List<int>>
.Dictionary
tidak tidak menawarkan kemampuan bi-directional. Jadi, jika semua yang Anda miliki adalah standarDictionary
dan Anda ingin menemukan kunci yang terkait dengan nilai tertentu, Anda memang harus mengulang! Namun, untuk kamus "besar", pengulangan dapat menghasilkan kinerja yang buruk. Perhatikan bahwa jawaban yang saya tawarkan sendiri didasarkan pada iterasi (melalui LINQ). Jika inisial AndaDictionary
tidak dapat diubah lebih lanjut, Anda dapat membuat pembalikanDictionary
satu kali untuk mempercepat pencarian terbalik.Gunakan LINQ untuk melakukan
Dictionary<K, V>
pencarian terbalik . Namun perlu diingat bahwa nilai dalamDictionary<K, V>
nilai Anda mungkin tidak berbeda.Demonstrasi:
Output yang Diharapkan:
sumber
sumber
Sebagai twist dari jawaban yang diterima ( https://stackoverflow.com/a/255638/986160 ) dengan asumsi bahwa kunci akan dikaitkan dengan nilai signle dalam kamus. Mirip dengan ( https://stackoverflow.com/a/255630/986160 ) tetapi sedikit lebih elegan. Kebaruannya adalah bahwa kelas konsumsi dapat digunakan sebagai alternatif enumerasi (tetapi untuk string juga) dan kamus mengimplementasikan IEnumerable.
Dan sebagai kelas konsumsi yang bisa Anda dapatkan
sumber
Lalu solusi orang awam
Sebuah fungsi yang mirip dengan yang di bawah ini dapat ditulis untuk membuat kamus seperti itu:
sumber