Forcing a LINQ KeyValuePair result list into a dictionary - lack of concept

I wanted to write a LINQ statement:

Dictionary<int, ItemBO> result = ( Dictionary<int, ItemBO> ) ( from item in originalResults where item.Value.SomeCriteria == true select item ); 

originalResults is of type Dictionary<int, ItemBO> .

I understand that item is of type KeyValuePair<int, ItemBO> , but I would have thought that casting from a list of this type into a dictionary of this type would be ... er ... "Natural".

Instead, to make the compiler shut up, I needed to write this:

 Dictionary<int, ItemBO> result = ( from item in originalResults where item.Value.SomeCriteria == true select item.Value ).ToDictionary( GetItemKey ); 

Which, although not entirely counter-intuitive, suggests that there is a lot of unnecessary work under the covers to unpack and repack the Dictionary. Is there a better solution? Is there a concept that I'm missing?

+6
dictionary list c # linq
source share
4 answers

Which, although not quite counter-intuitive, suggests that it covers up a lot of unnecessary work on unpacking and repacking the Dictionary.

I'm not sure what you mean by "unnecessary" work. A lot of work is required to complete this operation - your request must be fully evaluated, which involves scanning the entire dictionary and evaluating the predicate for each record. In addition, a new dictionary must be created and populated to store the results. I think that would be a problem if this work were hidden by automatic conversion.

The real problem is that you are using your dictionary back. Keyword searches are quick, but searching by value requires scanning all the items in the dictionary. If you can save the dictionary so that the value you use for filtering is the key, then you can do a much faster search with a stronger syntax.

+4
source share

I am going to strike again, what is the real concept of the "key" that you do not see.

If I dared to suggest, I would say that I think that you present Dictionary<TKey, TValue> as a synonym for its contents. You have a bunch of key-value pairs - this is a dictionary, right? And here you are missing an important detail. Although you could certainly implement IDictionary<TKey, TValue> using, say, a simple KeyValuePair<TKey, TValue>[] , this would be one of the biggest advantages of having a dictionary type in the first place: quick search by key.

Even if you saved an array that sorted and used binary search to find the keys (which, by the way, would bear the cost for all the inserts), you could not compete with the hash table that Dictionary<TKey, TValue> . This implementation is not just a bunch of key-value pairs without any particular structure; structure is everything for this type. Thus, a quick selection from a group of key-value pairs (content without structure) directly to the dictionary (with very specific structuring) is actually impossible - not that the structural layout of the type really determines whether casting is possible in C # in any case ( you must observe only inheritance and a few built-in and possibly user-defined transformation types).

Think of it this way: a dictionary is a container, not a content, right? Therefore, if I have a bunch of different cookies, and I want to extract all the cookies from the chocolate chips, I could extract them each, put them in a heap, and then say: “Now this is a jug of chocolate chip cookies, right?” No, I just took out the cookies; I have a bunch, not a jug. If I want a jug of chocolate chips, then I will have to put them in one, and this will require some non-zero amount of work.

+2
source share

The invalid concept is that your code is a query on an existing dictionary, the results of which will be IEnumerable<KeyValuePair<K,V>> . What your source code expects is that someone has defined a conversion for IEnumerable<KeyValuePair<K,V>> to Dictionary<K,V> . Essentially, they gave you the opportunity to determine what kind of transformation you need, since you have a ToDictionary extension method that allows you to define a key, value, etc.

+1
source share

The "real" result of a linq query is not a dictionary, so you cannot naturally drop it. The result is IQueryable, so you must explicitly convert it.

0
source share

All Articles