Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select multiple values from a Dictionary using Linq as simple as possible

I need to select a number of values (into a List) from a Dictionary based on a subset of keys.

I'm trying to do this in a single line of code using Linq but what I have found so far seems quite long and clumsy. What would be the shortest (cleanest) way to do this?

This is what I have now (the keys are Strings and keysToSelect is a List of keys to select):

List<ValueType> selectedValues = dictionary1.Where(x => keysToSelect.Contains(x.Key))
                                            .ToDictionary<String, valueType>(x => x.Key,
                                                                             x => x.Value)
                                            .Values.ToList;

Thank you.

like image 395
Peladao Avatar asked Sep 22 '12 15:09

Peladao


People also ask

How to use LINQ todictionary operator to convert a list to a dictionary?

In LINQ, the ToDictionary operator is useful to convert list/collection (IEnumerable<T>) items to a new dictionary object (Dictionary<TKey, TValue>), and it will optimize the list/collection items by getting only required values. Following is the syntax of using the LINQ ToDictionary operator to convert the collection to a new dictionary object.

What is select and selectmany operator in LINQ?

SelectMany Operator selects values from multiple or nested collection and flatten the result. You can understand Select and SelectMany Operator in LINQ more clearly when you will see the programming example. If you’ll read output carefully, you will notice that the Size is not displayed correctly.

How to select multiple Dept and name fields in LINQ?

var selectedLst=from item in employeesLst select item.Name; But if now we want to select multiple Dept and Name fields then we can not use this since this will be invalid syntax in LINQ: var selectedLst=from item in employeesLst select item.Id,item.Name; to handle such scenario we can use the anonymous type using the following syntax:

How do I select a value from a dictionary?

A Dictionary<TKey,TValue> is IEnumerable<KeyValuePair<TKey,TValue>>, so you can simply Select the Value property: List<ValueType> selectedValues = dictionary1 .Where (x => keysToSelect.Contains (x.Key)) .Select (x => x.Value) .ToList ();


4 Answers

Well you could start from the list instead of the dictionary:

var selectedValues = keysToSelect.Where(dictionary1.ContainsKey)
                     .Select(x => dictionary1[x])
                     .ToList();

If all the keys are guaranteed to be in the dictionary you can leave out the first Where:

var selectedValues = keysToSelect.Select(x => dictionary1[x]).ToList();

Note this solution is faster than iterating the dictionary, especially if the list of keys to select is small compared to the size of the dictionary, because Dictionary.ContainsKey is much faster than List.Contains.

like image 145
verdesmarald Avatar answered Oct 16 '22 21:10

verdesmarald


A Dictionary<TKey,TValue> is IEnumerable<KeyValuePair<TKey,TValue>>, so you can simply Select the Value property:

 List<ValueType> selectedValues = dictionary1
           .Where(x => keysToSelect.Contains(x.Key))
           .Select(x => x.Value)
           .ToList();

or

 var selectValues = (from keyValuePair in dictionary1
                     where keysToSelect.Contains(keyValuePair.Key)
                     select keyValuePair.Value).ToList()
like image 27
jeroenh Avatar answered Oct 16 '22 21:10

jeroenh


If you know that all the value that you want to select are in the dictionary, you can loop through the keys instead of looping through the dictionary:

List<ValueType> selectedValues = keysToSelect.Select(k => dictionary1[k]).ToList();
like image 3
Guffa Avatar answered Oct 16 '22 20:10

Guffa


The accepted answer is not very efficient when keys are not guaranteed to exist b/c it performs two lookups.

Based on the accepted answer I came up with this extension method:

public static IEnumerable<TValue> GetMultiple<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, IEnumerable<TKey> keysToSelect)
{
    foreach (var key in keysToSelect)
        if (dictionary.TryGetValue(key, out TValue value))
            yield return value;
}

Not exactly a "one liner" but I find it more readable than chaining four Linq methods.

Usage:

var results = dictionary.GetMultiple(keysToSelect).ToList()
like image 2
Alex from Jitbit Avatar answered Oct 16 '22 22:10

Alex from Jitbit