elementat c# dictionary

c# - elementat - Reverse many-to-many Dictionary<key, List<value>>



c# dictionary vs hashtable (3)

No estoy seguro exactamente en qué se diferencia esto de tu pregunta anterior .

Si solo pregunta cómo devolver un Dictionary<int, List<int>> lugar de Dictionary<int, IEnumerable<int>> , todo lo que necesita es una llamada al método ToList .

Robando y enmendando la respuesta de Mehrdad a tu otra pregunta :

var classToStudent = studentToClass .SelectMany( pair => pair.Value.Select(val => new { Key = val, Value = pair.Key })) .GroupBy(item => item.Key) .ToDictionary(gr => gr.Key, gr => gr.Select(item => item.Value).ToList());

En realidad, mi pregunta anterior me hizo pensar y me di cuenta de que revertir un Dictionary no es trivial. ¿Cuál es la forma más elegante y legible de hacerlo?

Mismo escenario estudiante Muchos a muchos con clases

original Dicitonary<int, List<int>> donde la clave es studentId y el Valor es una List<int> que contiene classId y desea volver al Dictionary<classId, List<studentId>>

Gracias

Actualización: en realidad, acabo de probar las soluciones de Luke y Bruno y me devuelven la cantidad correcta de personas clasificadas, ya que todas tienen el mismo estudiante, se actualizarán a medida que avanzo.


Para revertir un diccionario es muy fácil:

var newDic = oldDic.ToDictionary(x => x.Value, x => x.Key);

Eso es todo.

Ahora, tu pregunta es diferente. Se trata de revertir una relación de muchos a muchos, establecida en un diccionario.

Entonces, digamos que tiene el diccionario <TEntity1, IEnumerable <TEntity2>>. La idea es extraer de esto la "tabla intermedia" de la relación de muchos a muchos. Luego puede reagruparlo por el otro lado y volver a transformarse en un diccionario.

Para la primera parte, utilizaremos la sobrecarga de SelectMany que

"Proyecta cada elemento de una secuencia a un IEnumerable <T>, aplana las secuencias resultantes en una secuencia e invoca una función de selección de resultados en cada elemento".

var table = dict.SelectMany( x => x.Value, (dictEntry, entryElement) => new { Entity1 = dictEntry.Key, Entity2 = entryElement } );

Entonces, ahora solo tiene que reagrupar esta tabla de la forma que desee y luego convertirla en un diccionario.

var newDict = table .GroupBy(x => x.Entity2, x => x.Entity1, (entity2, entity1) => new {entity1, entity2}) .ToDictionary(x => x.entity2, x => x.entity1);


Una forma ligeramente diferente (un poco más comprensible para mi cerebro de todos modos :) ...

var newDict = new Dictionary<int, List<int>>(); var dict = new Dictionary<int, List<int>>(); dict.Add( 1, new List<int>() { 1, 2, 3, 4, 5 } ); dict.Add( 2, new List<int>() { 1, 2, 3, 4, 5 } ); dict.Add( 3, new List<int>() { 1, 2, 6 } ); dict.Add( 4, new List<int>() { 1, 6, 7 } ); dict.Add( 5, new List<int>() { 8 } ); var newKeys = dict.Values.SelectMany( v => v ).Distinct(); foreach( var nk in newKeys ) { var vals = dict.Keys.Where( k => dict[k].Contains(nk) ); newDict.Add( nk, vals.ToList() ); }