Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting from var to dictionary<String,int>

I have a dictionary defined as Dictionary<string, int> one

it has some data and I do the following LINQ on it

var temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5);

But now I want to convert it back into a `Dictionary

I tried using temp.ToDictionary(r => r.Key, r => r.Value);

But it tells me: Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer' because it is not a delegate type

How do I do this conversion?

like image 747
fotg Avatar asked Jun 11 '13 21:06

fotg


1 Answers

It's because you throw away the Value with the call to Select(r => r.Key). You'll need to keep the KeyValuePair together if you want to convert it back to a dictionary.

var temp = one.OrderBy(r => r.Value).Take(5);

var backToDictionary = temp.ToDictionary(r => r.Key, r => r.Value);

If you still want to have an IEnumerable<string> of the keys as in your question, you can use this separately:

var tempKeys = temp.Select(r => r.Key); 

The reason you're receiving a seemingly unrelated error message referring to an IEqualityComparer is because the compiler is attempting to make a best guess as to which overload you are attempting to call. Its best guess in this case thinks you were trying to call this overload.

Consider the code you had and the type it produced:

IEnumerable<string> temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5);

This would produce an object implementing IEnumerable<string>. Then with your call of:

temp.ToDictionary(r => r.Key, r => r.Value);

r in this case is string. The compiler at this point is freaking out because there's no such thing as r.Key nor r.Value. It recognizes that there are 2 parameters being used, and thus has two possible overloads to pick from for ToDictionary (this method, and this one). At this point, I'm not sure what the rules are for the compiler to choose one over the other (especially since it cannot infer the types of r.Key or r.Value), but it chose one of them. (perhaps it's simply the "first" one declared/found? Perhaps it favours direct object inputs over lambda expressions?) At any rate, it chooses the overload requiring an IEqualityComparer instead of a Func<TSource, TElement> and tells you (naturally) that a lambda expression is not convertable to IEqualityComprarer.

In my experience, once you feed the compiler garbage (r.Key and r.Value in this case), overload resolution kinda goes out the window. Sometimes it works out, usually when there is only one overload that matches the number parameters, or at least no ambiguity. But other times you just gotta see past the compiler error and fix the root problem.

like image 171
Chris Sinclair Avatar answered Sep 20 '22 19:09

Chris Sinclair