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.
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.
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.
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:
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 ();
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
.
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()
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();
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With