c#通过密钥列表从字典中获取值子集

时间:2012-02-27 11:18:49

标签: c# dictionary

好的,您可以按dictionary[key]获取单个值,或按dictionary.Values获取所有值。

我正在寻找的是获取给定键集的所有值的方法:

List<string> keys;
Dictionary<string, object> dictionary;

List<object> valuesForKeys = GetValuesFromDictionaryUsingKeys(dictionary, keys);

private List<object> GetValuesFromDictionaryUsingKeys(Dictionary<string, object> dictionary, List<string> keys)
{
    //your code here
}

当然我可以手动遍历密钥列表并每次使用dictionary[key]并再次将所有值添加回列表,但我想使用更优雅的方式(例如Linq)。

感谢。

6 个答案:

答案 0 :(得分:15)

尝试keys.Where(k => dictionary.ContainsKey(k)).Select(k => dictionary[k])

答案 1 :(得分:6)

为什么在日常使用时可以使用通用扩展方法来编写函数?

public static IEnumerable<V> GetValues<K, V>(this IDictionary<K, V> dict, IEnumerable<K> keys)
{
    return keys.Select((x) => dict[x]);
}

编辑: 你可以写下:

var  valuesForKeys = dictionary.GetValues(keys).ToList();

答案 2 :(得分:2)

private List<object> GetValuesFromDictionaryUsingKeys(Dictionary<string, object> dictionary, List<string> keys)
{
    List<object> nList = new List<object>();

    foreach (string sKey in keys)
        if (dictionary.ContainsKey(sKey))
            nList.Add(dictionary[sKey]);

    return nList;         
}

答案 3 :(得分:2)

尝试:

    List<object> valuesForKeys = keys.Intersect( dictionary.Keys )
                                     .Select( k => dictionary[k] )
                                     .ToList();

或按要求:

private List<object> GetValuesFromDictionaryUsingKeys( Dictionary<string, object> dictionary, List<string> keys )
{
    // My code here
    return keys.Intersect( dictionary.Keys )
               .Select( k => dictionary[k] )
               .ToList();     
}

使用 .Intersect 删除字典中不存在的密钥,速度比.Where(k => dictionary.ContainsKey(k))快。

删除.Intersect指令以允许引发异常以获取字典中未找到的密钥。

答案 4 :(得分:0)

Rawling的答案完美无瑕,但如果您事先知道字典上存在密钥,那么这可能会更清晰有效: keys.Select(k => dictionary[k])

答案 5 :(得分:0)

如果您正在寻找一种高性能的扩展方法(与本文中的其他答案相比)并且可以选择懒惰,我建议:

public static IEnumerable<V> ValuesFromIntersectedKeys<K, V>(this Dictionary<K, V> dic, IEnumerable<K> keys)
{
    V value;
    foreach (K k in keys)
    {
        if (dic.TryGetValue(k, out value))
            yield return value;
    }
}

public static IEnumerable<KeyValuePair<K, V>> IntersectKeys<K, V>(this Dictionary<K, V> dic, IEnumerable<K> keys)
{
    V value;
    foreach (K k in keys)
    {
        if (dic.TryGetValue(k, out value))
            yield return new KeyValuePair<K, V>(k, value);
    }
}

不在字典中的键被跳过,每次查找都利用字典哈希。此外,它的懒惰迭代。如果您想立即评估,只需对返回的结果调用 .ToList() 或 .ToArray() 即可。

还值得注意的是,KeyValuePair 是一个结构体(值类型),它将在堆栈上创建并在动态评估时保留在那里,这意味着在这种情况下 new 的成本与任何其他结构体值一样便宜类型。如果您调用 .ToList() 或 .ToArray() 或任何其他会导致堆分配的东西,您将不得不支付高昂的成本,但无论如何这是给定的。