Es un cruce entre an IGrouping
y un diccionario. Le permite agrupar elementos por una clave, pero luego acceder a ellos a través de esa clave de manera eficiente (en lugar de simplemente iterar sobre todos ellos, que es lo que le GroupBy
permite hacer).
Por ejemplo, podría tomar una carga de tipos .NET y crear una búsqueda por espacio de nombres ... luego acceder a todos los tipos en un espacio de nombres en particular muy fácilmente:
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);
}
}
}
(Normalmente lo usaría var
para la mayoría de estas declaraciones, en código normal).
Lookup<,>
es simplemente una colección inmutable (sinAdd
método, por ejemplo) que tiene un uso limitado. Además, no es una colección de propósito general en el sentido de que si busca una clave inexistente, obtiene una secuencia vacía en lugar de una excepción, que solo tiene sentido en contextos especiales, por ejemplo, con linq. Esto va bien con el hecho de que MS no ha proporcionado un constructor público para la clase.Una forma de pensarlo es esta:
Lookup<TKey, TElement>
es similar aDictionary<TKey, Collection<TElement>>
. Básicamente, se puede devolver una lista de cero o más elementos a través de la misma clave.fuente
Un uso de
Lookup
podría ser revertir aDictionary
.Suponga que tiene una agenda telefónica implementada como un
Dictionary
con un montón de nombres (únicos) como claves, cada nombre asociado con un número de teléfono. Pero dos personas con nombres diferentes pueden compartir el mismo número de teléfono. Esto no es un problema para aDictionary
, que no le importa que dos claves correspondan al mismo valor.Ahora desea una forma de buscar a quién pertenece un número de teléfono determinado. Construye un
Lookup
, agregando todoKeyValuePairs
de suDictionary
, pero al revés, con el valor como clave y la clave como valor. Ahora puede consultar un número de teléfono y obtener una lista de nombres de todas las personas cuyo número de teléfono es ese. Construir un archivoDictionary
con los mismos datos los eliminaría (o fallaría, dependiendo de cómo lo hiciera), yasignifica que la segunda entrada sobrescribe la primera; el Doc ya no aparece en la lista.
Intentando escribir los mismos datos de una manera ligeramente diferente:
arrojaría una excepción en la segunda línea ya que no puede
Add
una clave que ya está en elDictionary
.[Por supuesto, es posible que desee utilizar alguna otra estructura de datos única para realizar búsquedas en ambas direcciones, etc. Este ejemplo significa que tiene que regenerar el
Lookup
deDictionary
cada vez que este último cambia. Pero para algunos datos podría ser la solución correcta.]fuente
No lo he usado con éxito antes, pero aquí está mi ir:
A
Lookup<TKey, TElement>
se comportaría más o menos como un índice de base de datos (relacional) en una tabla sin una restricción única. Úselo en los mismos lugares donde usaría el otro.fuente
Creo que podría argumentarlo de esta manera: imagine que está creando una estructura de datos para contener el contenido de una guía telefónica. Desea escribir por apellido y luego por nombre. Usar un diccionario aquí sería peligroso porque muchas personas pueden tener el mismo nombre. Por lo tanto, un Diccionario siempre, como máximo, se asignará a un solo valor.
Una búsqueda se asignará a potencialmente varios valores.
La búsqueda ["Smith"] ["John"] será una colección de tamaño mil millones.
fuente
Lookup["Smith"]["John"]
?