简体   繁体   中英

How to get a list of filtered values in Dictionary into a List using LINQ or Lambda?

I have two Lists: ListA and ListB as well as a Dictionary DictA.

I am going through all the values of ListA and I want to return the "Value" of DictA into ListB.

At the moment I am doing it as follows:

ListA = ...
foreach(var x in ListA) {
    if(DictA.ContainsKey(x))
    {
         ListB.add(DictA[x]);
    }
}

How do I do that in Lambda or LINQ?

You could do this (a pretty direct translation of your code):

ListB.AddRange(ListA.Where(t => DictA.ContainsKey(t)).Select(t => DictA[t]));

If you're sure all ListA values exist in the dictionary, then you can remove the .Where(..) and leave just the .Select(..) .

If ListB is to contain only these values, then you could re-arrange things slightly:

var ListB = ListA.Where(t => DictA.ContainsKey(t)).Select(t => DictA[t]).ToList();

Alternative method (might be faster):

var ListB = ListA.Intersect(DictA.Keys).Select(t => DictA[t]).ToList();

First of all, if you are not using TryGetValue, then you are doing object search twice, as first ContainsKey and then retrieving object. In terms of best performance, this should be the case.

 var ListB = ListA.Select<TypeA>( x=> { 
              TypeA a = null; 
              DictA.TryGetValue(x, out a);
              return a; }).Where( x=> x != null).ToList();

In above case, you are enumerating your list only once and you are retrieving the item also only once.

You can write an extension method as below to reuse this,

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;
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM