Ini adalah persilangan antara IGrouping
dan kamus. Ini memungkinkan Anda mengelompokkan item bersama dengan kunci, tetapi kemudian mengaksesnya melalui kunci itu dengan cara yang efisien (bukan hanya iterasi atas semuanya, yang GroupBy
memungkinkan Anda melakukannya).
Sebagai contoh, Anda dapat mengambil banyak jenis .NET dan membangun pencarian berdasarkan namespace ... kemudian mendapatkan semua jenis dalam namespace tertentu dengan sangat mudah:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
public class Test
{
static void Main()
{
// Just types covering some different assemblies
Type[] sampleTypes = new[] { typeof(List<>), typeof(string),
typeof(Enumerable), typeof(XmlReader) };
// All the types in those assemblies
IEnumerable<Type> allTypes = sampleTypes.Select(t => t.Assembly)
.SelectMany(a => a.GetTypes());
// Grouped by namespace, but indexable
ILookup<string, Type> lookup = allTypes.ToLookup(t => t.Namespace);
foreach (Type type in lookup["System"])
{
Console.WriteLine("{0}: {1}",
type.FullName, type.Assembly.GetName().Name);
}
}
}
(Saya biasanya menggunakan var
sebagian besar deklarasi ini, dalam kode normal.)
Lookup<,>
hanyalah koleksi abadi (tanpaAdd
metode misalnya) yang memiliki penggunaan terbatas. Selain itu, ini bukan kumpulan tujuan umum dalam arti bahwa jika Anda mencari pada kunci yang tidak ada Anda mendapatkan urutan kosong daripada pengecualian, yang hanya bermakna dalam konteks khusus, misalnya, dengan linq. Ini sejalan dengan fakta bahwa MS belum menyediakan konstruktor publik untuk kelas tersebut.Salah satu cara untuk memikirkannya adalah ini:
Lookup<TKey, TElement>
mirip denganDictionary<TKey, Collection<TElement>>
. Pada dasarnya daftar elemen nol atau lebih dapat dikembalikan melalui kunci yang sama.sumber
Salah satu penggunaan
Lookup
bisa untuk membalikkan aDictionary
.Misalkan Anda memiliki buku telepon yang diimplementasikan sebagai
Dictionary
dengan sekelompok (unik) nama sebagai kunci, masing-masing nama yang terkait dengan nomor telepon. Tetapi dua orang dengan nama berbeda mungkin berbagi nomor telepon yang sama. Ini bukan masalah untuk aDictionary
, yang tidak peduli bahwa dua kunci sesuai dengan nilai yang sama.Sekarang Anda ingin cara mencari tahu milik siapa nomor telepon tertentu. Anda membangun
Lookup
, menambahkan semuaKeyValuePairs
dari AndaDictionary
, tetapi mundur, dengan nilai sebagai kunci dan kunci sebagai nilai. Anda sekarang dapat meminta nomor telepon, dan mendapatkan daftar nama semua orang yang memiliki nomor telepon itu. MembangunDictionary
dengan data yang sama akan menghapus data (atau gagal, tergantung bagaimana Anda melakukannya), sejak melakukannyaberarti bahwa entri kedua menimpa yang pertama - Doc tidak lagi terdaftar.
Mencoba menulis data yang sama dengan cara yang sedikit berbeda:
akan melemparkan pengecualian pada baris kedua karena Anda tidak dapat
Add
kunci yang sudah ada diDictionary
.[Tentu saja, Anda mungkin ingin menggunakan beberapa struktur data tunggal untuk melakukan pencarian di kedua arah, dll. Contoh ini berarti bahwa Anda harus membuat ulang
Lookup
dariDictionary
setiap kali perubahan terakhir. Tetapi untuk beberapa data itu bisa menjadi solusi yang tepat.]sumber
Saya belum berhasil menggunakannya sebelumnya, tapi ini dia:
A
Lookup<TKey, TElement>
akan berperilaku seperti indeks basis data (relasional) di atas meja tanpa kendala yang unik. Gunakan di tempat yang sama dengan yang lain.sumber
Saya kira Anda bisa berdebat seperti ini: bayangkan Anda sedang membuat struktur data untuk menyimpan konten buku telepon. Anda ingin memasukkan oleh lastName dan kemudian oleh firstName. Menggunakan kamus di sini akan berbahaya karena banyak orang dapat memiliki nama yang sama. Jadi Kamus akan selalu, paling banyak, memetakan ke nilai tunggal.
Pencarian akan memetakan ke beberapa nilai yang berpotensi.
Pencarian ["Smith"] ["John"] akan menjadi koleksi ukuran satu miliar.
sumber
Lookup["Smith"]["John"]
?