如何尽可能简单地使用Linq从字典中选择多个值

vwkv1x7d  于 2022-12-06  发布在  其他
关注(0)|答案(5)|浏览(111)

我需要根据键的子集从字典中选择一些值(放入列表中)。
我试图用Linq在一行代码中完成这个任务,但是到目前为止我发现这个任务似乎很长很笨拙。什么是最短(最干净)的方法呢?
这就是我现在所拥有的(键是字符串,而keysToSelect是要选择的键的列表):

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

7z5jn7bk1#

你可以从清单而不是字典开始:

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

如果所有的键都在字典中,你可以省略第一个Where

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

注意,这种解决方案比迭代字典要快,尤其是当要选择的键列表与字典的大小相比很小时,因为Dictionary.ContainsKeyList.Contains快得多。

muk1a3rh

muk1a3rh2#

一个Dictionary<TKey,TValue>就是IEnumerable<KeyValuePair<TKey,TValue>>,所以你可以简单地把ValueSelect属性:

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

var selectValues = (from keyValuePair in dictionary1
                     where keysToSelect.Contains(keyValuePair.Key)
                     select keyValuePair.Value).ToList()
4dbbbstv

4dbbbstv3#

如果您知道要选择的所有值都在字典中,则可以循环遍历键,而不是循环遍历字典:

List<ValueType> selectedValues = keysToSelect.Select(k => dictionary1[k]).ToList();
v6ylcynt

v6ylcynt4#

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()
avwztpqn

avwztpqn5#

The accepted solution is still not the most efficient option from the point of lookups as you still have to check if the key is in the dictionary twice: once to filter the keys, once to lookup the object.
This solution does not have that issue:

var selectedValues = keysToSelect
  .Select(_ => {
     var found = dict.TryGetValue(_, out TValue? result);
     return (found, result);
  })
  .Where(_ => _.found)
  .Select(_ => _.result!)
  .ToList();

相关问题