【问题标题】:How to get a list of filtered values in Dictionary into a List using LINQ or Lambda?如何使用 LINQ 或 Lambda 将字典中的过滤值列表获取到列表中?
【发布时间】:2015-03-20 03:29:23
【问题描述】:
我有两个列表:ListA 和 ListB 以及一个 Dictionary DictA。
我正在检查 ListA 的所有值,我想将 DictA 的“值”返回到 ListB。
目前我的做法如下:
ListA = ...
foreach(var x in ListA) {
if(DictA.ContainsKey(x))
{
ListB.add(DictA[x]);
}
}
如何在 Lambda 或 LINQ 中做到这一点?
【问题讨论】:
标签:
c#
linq
dictionary
lambda
【解决方案1】:
您可以这样做(对您的代码进行非常直接的翻译):
ListB.AddRange(ListA.Where(t => DictA.ContainsKey(t)).Select(t => DictA[t]));
如果您确定字典中存在所有 ListA 值,则可以删除 .Where(..) 并仅保留 .Select(..)。
如果ListB 只包含这些值,那么您可以稍微重新安排一下:
var ListB = ListA.Where(t => DictA.ContainsKey(t)).Select(t => DictA[t]).ToList();
替代方法(可能更快):
var ListB = ListA.Intersect(DictA.Keys).Select(t => DictA[t]).ToList();
【解决方案2】:
首先,如果您没有使用 TryGetValue,那么您将执行两次对象搜索,首先是 ContainsKey,然后是检索对象。就最佳性能而言,应该是这样。
var ListB = ListA.Select<TypeA>( x=> {
TypeA a = null;
DictA.TryGetValue(x, out a);
return a; }).Where( x=> x != null).ToList();
在上述情况下,您仅枚举您的列表一次,并且您也仅检索该项目一次。
您可以编写如下扩展方法来重用它,
public static IEnumerable<TValue> ToFilteredValues<TKey,TValue>(
this IDictionary<TKey,TValue> dict,
IEnumerable<TKey> list){
TValue value;
foreach(var key in list){
if(dict.TryGetValue(key, out value))
yield return value;
}
}