Estoy buscando una clase de diccionario 1 a 1 bidireccional genérica en C # (2), es decir. a BiDictionaryOneToOne<T, S>que está garantizado para contener solo uno de cada valor y clave (hasta RefEquals de todos modos), y que se puede buscar utilizando la clave o el valor. ¿Alguien sabe de uno, o debería implementarlo yo mismo? No puedo creer que sea la primera persona en necesitar esto ...
Hay un BiDictionary en las respuestas a esta pregunta , pero no es para elementos únicos (y tampoco implementa RemoveByFirst (T t) o RemoveBySecond (S s)).
¡Gracias!
c#
.net
collections
Joel en Gö
fuente
fuente

Respuestas:
OK, aquí está mi intento (basado en el de Jon, gracias), archivado aquí y abierto para mejoras:
fuente
Una implementación más completa del diccionario bidireccional:
Dictionary<TKey,TValue>(excepto las interfaces de infraestructura):IDictionary<TKey, TValue>IReadOnlyDictionary<TKey, TValue>IDictionaryICollection<KeyValuePair<TKey, TValue>>(esta y las siguientes son las interfaces base de las anteriores)ICollectionIReadOnlyCollection<KeyValuePair<TKey, TValue>>IEnumerable<KeyValuePair<TKey, TValue>>IEnumerableSerializableAttribute.DebuggerDisplayAttribute(con información de recuento) yDebuggerTypeProxyAttribute(para mostrar pares clave-valor en relojes).IDictionary<TValue, TKey> Reversepropiedad y también implementa todas las interfaces mencionadas anteriormente. Todas las operaciones en cualquiera de los diccionarios modifican ambos.Uso:
El código está disponible en mi marco privado en GitHub: BiDictionary (TFirst, TSecond) .cs ( enlace permanente , búsqueda ).
Copiar:
fuente
item.Reverselíneas. ¿Algún requisito de versión en particular?KeyValuePairExtsclase al final del fragmento de código.La pregunta a la que hace referencia también muestra una implementación uno a uno en esta respuesta . Agregar RemoveByFirst y RemoveBySecond sería trivial, al igual que implementar interfaces adicionales, etc.
fuente
Esta es la misma que la respuesta aceptada, pero también proporcioné
Updatemétodos y, sobre todo, un poco más desarrollado:Similar a mi respuesta aquí
Algunas cosas a tener en cuenta:
Solo he implementado
IEnumerable<>. No creo queICollection<>tenga sentido aquí, ya que los nombres de los métodos podrían ser muy diferentes para esta estructura de colección especial. Depende de usted decidir qué debe ir dentroIEnumerable<>. Así que ahora también tiene la sintaxis del inicializador de colección, comoHe intentado lanzar algunas excepciones extrañas aquí y allá, solo para la integridad de los datos. Solo para estar más seguro y saber si alguna vez mi código tiene errores.
Rendimiento: puede buscar
Valuecon cualquiera de losKeysmediosGetyContainsmétodos que requieren solo 1 búsqueda (O (1)).Addrequiere 2 búsquedas y 2 adiciones.Updaterequiere 1 búsqueda y 2 adiciones.Removetoma 3 búsquedas. Todo similar a la respuesta aceptada.fuente
IEnumerator<Tuple<TKey1, TKey2>>aquí. NoIEnumerator<KeyValuePair<TKey1, TKey2>>, así que creo que no puedo hacer eso con mi función GetEnumerator. ¿Te entendí correctamente?He creado una clase de este tipo, utilizando clases de colección C5.
fuente
Otra extensión de la respuesta aceptada. Implementa IEnumerable para que uno pueda usar foreach con eso. Me doy cuenta de que hay más respuestas con la implementación de IEnumerable, pero esta usa estructuras, por lo que es compatible con el recolector de basura . Esto es especialmente útil en el motor Unity (verificado con el generador de perfiles).
fuente
Un poco tarde, pero aquí hay una implementación que escribí hace un tiempo. Maneja algunos casos extremos interesantes, como cuando la clave anula la verificación de igualdad para realizar una igualdad parcial. Esto da como resultado el almacenamiento del diccionario principal
A => 1pero el almacenamiento inverso1 => A'.Se accede al diccionario inverso a través de la
Inversepropiedad.Fuente original y pruebas en github.
fuente