Saya mencari kelas kamus 1 ke 1 generik, dua arah di C # (2), yaitu. a BiDictionaryOneToOne<T, S>
yang dijamin hanya berisi satu dari setiap nilai dan kunci (tetap hingga RefEquals), dan yang dapat dicari menggunakan kunci atau nilai. Ada yang tahu, atau haruskah saya menerapkannya sendiri? Saya tidak percaya bahwa saya orang pertama yang membutuhkan ini ...
Ada BiDictionary dalam jawaban atas pertanyaan ini , tetapi bukan untuk elemen unik (dan juga tidak menerapkan RemoveByFirst (T t) atau RemoveBySecond (S s)).
Terima kasih!
c#
.net
collections
Joel di Gö
sumber
sumber
Jawaban:
Oke, inilah upaya saya (membangun dari Jon - terima kasih), diarsipkan di sini dan terbuka untuk perbaikan:
sumber
Penerapan kamus dua arah yang lebih lengkap:
Dictionary<TKey,TValue>
(kecuali antarmuka infrastruktur):IDictionary<TKey, TValue>
IReadOnlyDictionary<TKey, TValue>
IDictionary
ICollection<KeyValuePair<TKey, TValue>>
(yang ini dan di bawah ini adalah antarmuka dasar dari yang di atas)ICollection
IReadOnlyCollection<KeyValuePair<TKey, TValue>>
IEnumerable<KeyValuePair<TKey, TValue>>
IEnumerable
SerializableAttribute
.DebuggerDisplayAttribute
(dengan info Hitungan) danDebuggerTypeProxyAttribute
(untuk menampilkan pasangan nilai kunci di jam tangan).IDictionary<TValue, TKey> Reverse
properti dan juga mengimplementasikan semua antarmuka yang disebutkan di atas. Semua operasi pada salah satu kamus mengubah keduanya.Pemakaian:
Code tersedia dalam rangka pribadi saya di GitHub: BiDictionary (TFirst, TSecond) Cs ( permalink , pencarian ).
Menyalin:
sumber
item.Reverse
baris Anda . Ada persyaratan versi tertentu?KeyValuePairExts
kelas di bagian bawah cuplikan kode.Pertanyaan yang Anda rujuk juga menunjukkan implementasi satu-ke-satu dalam jawaban ini . Menambahkan RemoveByFirst dan RemoveBySecond akan menjadi hal yang sepele - seperti menerapkan antarmuka tambahan, dll.
sumber
Ini sama dengan jawaban yang diterima, tetapi saya juga menyediakan
Update
metode, dan lebih dari itu semua sedikit lebih lengkap:Mirip dengan jawaban saya di sini
Beberapa hal yang perlu diperhatikan:
Saya hanya menerapkan
IEnumerable<>
. Saya rasa tidakICollection<>
masuk akal di sini karena semua nama metode bisa sangat berbeda untuk struktur koleksi khusus ini. Terserah Anda untuk memutuskan apa yang harus masuk ke dalamIEnumerable<>
. Jadi sekarang Anda juga memiliki sintaks penginisialisasi koleksi, sepertiSaya telah mencoba beberapa pengecualian aneh untuk dilemparkan ke sana-sini - hanya untuk integritas data. Hanya untuk berada di sisi yang lebih aman sehingga Anda tahu jika kode saya memiliki bug.
Kinerja: Anda dapat mencari
Value
dengan salah satu caraKeys
, yang artinyaGet
danContains
metode hanya memerlukan 1 pencarian (O (1)).Add
membutuhkan 2 pencarian dan 2 penambahan.Update
membutuhkan 1 pencarian dan 2 penambahan.Remove
membutuhkan 3 pencarian. Semua serupa dengan jawaban yang diterima.sumber
IEnumerator<Tuple<TKey1, TKey2>>
sini. TidakIEnumerator<KeyValuePair<TKey1, TKey2>>
, jadi saya rasa saya tidak bisa melakukan itu ke fungsi GetEnumerator saya. Apakah saya mengerti Anda dengan benar?Saya telah membuat kelas seperti itu, menggunakan kelas koleksi C5.
sumber
Perpanjangan lain untuk jawaban yang diterima. Ini mengimplementasikan IEnumerable sehingga seseorang dapat menggunakan foreach dengan itu. Saya menyadari ada lebih banyak jawaban dengan implementasi IEnumerable tetapi yang ini menggunakan struct sehingga ramah pengumpul sampah . Ini sangat berguna di mesin Unity (diperiksa dengan profiler).
sumber
Agak terlambat, tapi inilah implementasi yang saya tulis beberapa waktu lalu. Ini menangani beberapa kasus edge yang menarik, seperti saat kunci mengganti pemeriksaan kesetaraan untuk melakukan persamaan parsial. Ini menghasilkan penyimpanan kamus utama
A => 1
tetapi penyimpanan terbalik1 => A'
.Anda mengakses kamus terbalik melalui
Inverse
properti.Sumber asli dan tes di github.
sumber