我有两个列表:ListA和ListB以及Dictionary DictA。
我正在浏览ListA的所有值,我想返回" Value" DictA进入ListB。
目前我正在按如下方式进行:
ListA = ...
foreach(var x in ListA) {
if(DictA.ContainsKey(x))
{
ListB.add(DictA[x]);
}
}
我如何在Lambda或LINQ中执行此操作?
答案 0 :(得分:2)
你可以这样做(代码的直接翻译):
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();
答案 1 :(得分:1)
首先,如果您没有使用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;
}
}