C # Convertir lista <cadena> a diccionario <cadena, cadena>

117

Esto puede parecer algo extraño, pero ignorando eso, ¿existe una forma concisa y agradable de convertir una lista en diccionario donde cada par de valores clave en el diccionario es solo cada cadena en la lista? es decir

List = string1, string2, string3
Dictionary = string1/string1, string2/string2, string3/string3

He realizado muchas búsquedas y hay literalmente docenas de ejemplos en Stackoverflow solo de hacerlo en la dirección opuesta pero no de esta manera.

La razón para hacer esto es que tengo dos componentes de terceros y cambiarlos está fuera de mis manos. Uno devuelve una lista de direcciones de correo electrónico como una Lista y el otro envía correos electrónicos donde el parámetro Para es un Diccionario. La clave del diccionario es la dirección de correo electrónico y el valor es su nombre real. Sin embargo, no sé el nombre real, pero aún funciona si también establece el nombre real en la dirección de correo electrónico. Por lo tanto, ¿por qué quiero convertir una lista en un diccionario? Hay muchas formas de hacer esto. Un bucle foreach en la lista que agrega un kvp a un diccionario. Pero me gusta el código conciso y me preguntaba si habría una solución de una sola línea.

Jonnster
fuente
1
Tengo una mejor solución por tu razón válida, honesto.
2
Es posible que desee ver si HashSet <> cumple con sus requisitos, en lugar de usar Dictionary <,>.
Greg
Más directamente que los comentaristas anteriores: si explica la razón por la que desea esto, probablemente alguien pueda sugerir una solución mejor.
Tim S.
1
No hay mejor solución. Tengo un componente de terceros que devuelve una lista de cadenas, estas son direcciones de correo electrónico. Tengo otro componente de terceros que envía correos electrónicos donde pasa un Dictionary <string, string> donde la clave es la dirección de correo electrónico y el valor es el nombre real del destinatario. Sin embargo, el nombre real también puede ser la dirección de correo electrónico nuevamente, por lo que quiero convertir una List <string> en un Dictionary <string, string>
Jonnster

Respuestas:

243

Prueba esto:

var res = list.ToDictionary(x => x, x => x);

La primera lambda le permite elegir la clave, la segunda elige el valor.

Puedes jugar con él y hacer que los valores difieran de las teclas, así:

var res = list.ToDictionary(x => x, x => string.Format("Val: {0}", x));

Si su lista contiene duplicados, agregue Distinct()así:

var res = list.Distinct().ToDictionary(x => x, x => x);

EDITAR Para comentar la razón válida, creo que la única razón que podría ser válida para conversiones como esta es que en algún momento las claves y los valores en el diccionario resultante van a divergir. Por ejemplo, haría una conversión inicial y luego reemplazaría algunos de los valores con algo más. Si las claves y los valores siempre van a ser los mismos, HashSet<String>se adaptarían mucho mejor a su situación:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...
dasblinkenlight
fuente
esto fallará si la lista es como cadena1, cadena2, cadena3, cadena1
Pranay Rana
3
@PranayRana Sí, lo haría. Puede agregar .Distinct()después listpara evitar esto.
dasblinkenlight
Gracias. Eché de menos la función ToDictionary. Gracias a todos los que básicamente dieron la misma respuesta. Voté a todos, pero solo puedo aceptar una respuesta. Este fue solo uno con el código Distinct agregado, por lo que fue el más completo en mi opinión.
Jonnster
11

Utilizar este:

var dict = list.ToDictionary(x => x);

Consulte MSDN para obtener más información.

Como señala Pranay en los comentarios, esto fallará si un elemento existe en la lista varias veces.
Dependiendo de sus requisitos específicos, puede usar var dict = list.Distinct().ToDictionary(x => x);para obtener un diccionario de elementos distintos o puede usar ToLookupen su lugar:

var dict = list.ToLookup(x => x);

Esto devolverá un ILookup<string, string>que es esencialmente el mismo que IDictionary<string, IEnumerable<string>>, por lo que tendrá una lista de claves distintas con cada instancia de cadena debajo.

Daniel Hilgarth
fuente
esto fallará si la lista es como cadena1, cadena2, cadena3, cadena1
Pranay Rana
1

Utilizando ToDictionary:

var dictionary = list.ToDictionary(s => s);

Si es posible que se repita cualquier cadena, Distinctprimero haga una llamada en la lista (para eliminar los duplicados), o use la ToLookupque permita múltiples valores por clave.

Lukazoide
fuente
0

Puedes usar:

var dictionary = myList.ToDictionary(x => x);
dtsg
fuente
0

EDITAR

otra forma de lidiar con los duplicados es hacerlo así

var dic = slist.Select((element, index)=> new{element,index} )
            .ToDictionary(ele=>ele.index.ToString(), ele=>ele.element);

o


una forma fácil de hacerlo es

var res = list.ToDictionary(str => str, str=> str); 

pero asegúrese de que no haya una cadena que se repita ... nuevamente, de lo contrario, el código anterior no funcionará para usted

si hay una cadena que se repite, es mejor hacerlo así

Dictionary<string,string> dic= new Dictionary<string,string> ();

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Pranay Rana
fuente