Using .ToDictionary()

I have a method returning a List, let's call it GetSomeStrings().

I have an extension method on string class, returning number of characters in the string, eg. myString.Number('A').

I would like to, in a single line, grab a dictionary. An entry of the dictionary contains the string, and the number of a chosen character in the string.

Actually I do the following:

var myDic = GetSomeStrings().ToDictionary(x=>x.Number('A'));

这给了我一本字典<int,string>。我想把钥匙当绳子。

After, I'd like to order the dictionary on the int value. It is possible to include this in the previous statement ?

I'd really like to avoid a collection enumeration to sort or create the dictionary from the list, which is what i do actually without troubles. Thank you for your optimization help !

127397 次浏览

Edit

The ToDictionary() method has an overload that takes two lambda expressions (nitpick: delegates); one for the key and one for the value.

For example:

var myDic = GetSomeStrings().ToDictionary(x => x, x => x.Number('A'));

Note that the values returned by GetSomeStrings() must be unique.


.Net's Dictionary<TKey, TValue> is unordered; it cannot be sorted at all.

Instead, you can sort the dictionary when you use it, like this:

foreach(KeyValuePair<string, int> kvp in dict.OrderBy(kvp => kvp.Value))

To construct your dictionary, you can do this:

var strings = new[] { "one", "2", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
var dictionary = strings.GroupBy(x => x.Length.ToString()).ToDictionary(x => x.Key, x => x);

Notice the "ToString()" usage to turn the Length of the string into a string.

Also, sorting a dictionary doesn't generally make sense. You can sort the items in each key of the dictionary, or you can sort the keys of the dictionary when you want to loop through them.

var sortedKeys = dictionary.Keys.OrderBy(x => x);
var sortedValues = dictionary["1"].OrderBy(x => x);

A regular Dictionary is not sorted, but you can use a SortedDictionary:

var sortedDict = new SortedDictionary<string, int>(
GetSomeStrings().ToDictionary(x => x, y => y.Number('A')));

That should give you a SortedDictionary<string, int> sorted by the string key.

You need to use the overload of ToDictionary which takes two functions:

 var myDic = GetSomeStrings().ToDictionnary(x => x, x => x.Number('A'));

Both functions take what ever object you are using to create the dictionary. The first produces the Key; the second, the Value.

var myDic = GetSomeStrings()
.ToDictionary(x => x, x => x.Number('A'));

Gets you the dictionary in your intended way.

Edit: Added Order by. First orders the strings, then puts them into the dict, as you liked

Edit2: Slaks is right. OrderBy would have no effect. Removed it again

If I understand the question correctly, here is my solution:

var myDic = GetSomeStrings()
.Select(x => new KeyValuePair<string, int>(x, x.Number('A')))
.ToDictionary(t => t.Key, t => t.Value);
var users = this.context.ad_user.ToDictionary(v => v.DistinguishedName,
v => new ad_user
{
DistinguishedName = v.DistinguishedName,
CN = v.CN,
DisplayName = v.DisplayName,
Info = v.Info,
Mail = v.Mail
});