180

This may seem an odd thing to want to do but ignoring that, is there a nice concise way of converting a List<string> to Dictionary<string, string> where each Key Value Pair in the Dictionary is just each string in the List. i.e.

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

I have done plenty of searching and there are literally dozens of examples on Stackoverflow alone of doing it in the opposite direction but not this way round.

The reason for doing this is I have two third part components and changing them is out of my hands. One returns a list of email addresses as a List<string> and the other send emails where the To parameter is a Dictionary<string, string>. The key of the dictionary is the email address and the value is their real name. However, I don't know the real name but it still works if you set the real name to the email address as well. Therefore why I want to convert a List to a Dictionary<string, string>. There are plenty of ways of doing this. A foreach loop on the list which adds a kvp to a dictionary. But I like terse code and wondered if there was a single line solution.

Selim Yildiz
  • 5,254
  • 6
  • 18
  • 28
Jonnster
  • 3,094
  • 5
  • 33
  • 45
  • 1
    I have a better solution for your valid reason, honest. –  Jul 20 '12 at 14:15
  • 2
    You may want to see if HashSet<> meets your requirements, instead of using Dictionary<,>. – Greg Jul 20 '12 at 14:15
  • More directly than the above commenters: If you explain your reason for wanting this, someone can probably suggest a better solution. – Tim S. Jul 20 '12 at 14:25
  • 1
    There is no better solution. I have a third party component that returns a list of strings these are email addresses. I have another third party component that sends emails where it passes a Dictionary where the key is the email address and value is the recipients real name. However, the real name can also just be the email address again which is why I want to convert a List to a Dictionary – Jonnster Jul 20 '12 at 14:36

5 Answers5

359

Try this:

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

The first lambda lets you pick the key, the second one picks the value.

You can play with it and make values differ from the keys, like this:

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

If your list contains duplicates, add Distinct() like this:

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

EDIT To comment on the valid reason, I think the only reason that could be valid for conversions like this is that at some point the keys and the values in the resultant dictionary are going to diverge. For example, you would do an initial conversion, and then replace some of the values with something else. If the keys and the values are always going to be the same, HashSet<String> would provide a much better fit for your situation:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • this will fail if list is like string1, string2, string3,string1 – Pranay Rana Jul 20 '12 at 14:16
  • 6
    @PranayRana Yes, it would. You can add `.Distinct()` after `list` to avoid this. – Sergey Kalinichenko Jul 20 '12 at 14:19
  • Thanks. I missed the ToDictionary function. Thanks to everyone who basically gave the same answer. I upvoted everyone but can only accept one answer. This one was only one with the Distinct code added so was the most complete in my opinion. – Jonnster Jul 20 '12 at 15:29
18

Use this:

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

See MSDN for more info.

As Pranay points out in the comments, this will fail if an item exists in the list multiple times.
Depending on your specific requirements, you can either use var dict = list.Distinct().ToDictionary(x => x); to get a dictionary of distinct items or you can use ToLookup instead:

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

This will return an ILookup<string, string> which is essentially the same as IDictionary<string, IEnumerable<string>>, so you will have a list of distinct keys with each string instance under it.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
11

EDIT

another way to deal with duplicate is you can do like this

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

or


easy way to do is

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

but make sure that there is no string is repeating...again otherewise above code will not work for you

if there is string is repeating than its better to do like this

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

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
3

By using ToDictionary:

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

If it is possible that any string could be repeated, either do a Distinct call first on the list (to remove duplicates), or use ToLookup which allows for multiple values per key.

Lukazoid
  • 19,016
  • 3
  • 62
  • 85
1

You can use:

var dictionary = myList.ToDictionary(x => x);
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
dtsg
  • 4,408
  • 4
  • 30
  • 40