使用linq表达式过滤带有键列表的字典

时间:2015-09-04 11:37:59

标签: c# linq

我有一本字典,其中包含所有具有相应年龄的用户。

Dictionary<string,int> AllUsers;

我有一个特定用户列表。

List<String> Users;

我想仅使用AllUsers列表中名称相同的用户过滤第一个字典SpecificUsers

我已经使用循环手动完成了某些操作,但我想使用linq表达式,但我对它们并不是很熟悉。

提前感谢您的帮助

5 个答案:

答案 0 :(得分:4)

它可能有效

var newdict = AllUsers.Where(x => Users.Contains(x.Key))
                                        .ToDictionary(val => val.Key, val => val.Value);

它会在Users列表中的字典中创建新字典(因为linq用于查询而不是更新)。您需要使用ToDictionary来实际制作字典。

编辑: 正如@Rawling所说,过滤词典而不是列表会更有效。 @Luaan答案中存在解决方案(我不会像其他人那样复制)

答案 1 :(得分:3)

您可以过滤Users

Users.Where(i => AllUsers.ContainsKey(i)).Select(i => new { User = i, Age = AllUsers[i] });

这样做的主要好处是您使用索引AllUsers进行过滤,因此您的总计算复杂度仅取决于Users中的用户数量(Dictionary.Contains是O(1)) - 天真的方法往往是Users * AllUsers

如果您想要输出字典,就像用

替换上面的.Select(...)一样简单
.ToDictionary(i => i, i => AllUsers[i])

答案 2 :(得分:3)

您可以使用join()方法实际加入这两个集合。它允许我们用一行linq获得你需要的东西。

var allUsers    = new Dictionary<string, int>();
allUsers.Add("Bob", 10);
allUsers.Add("Tom", 20);
allUsers.Add("Ann", 30);

var users       = new List<string>();
users.Add("Bob");
users.Add("Tom");
users.Add("Jack");

var result  = allUsers.Join(users, o => o.Key, i => i, (o, i) => o);
foreach(var r in result)
{
    Console.WriteLine(r.Key + " " + r.Value);
}

它将在控制台中输出以下内容:

Bob 10
Tom 20

结果集中只有两个集合中出现的名称可用

答案 3 :(得分:1)

有多种方法可以做到这一点

您可以使用where关键字

来使用此功能
 var result= yourDictionary.Where(p=> yourList.Contains(p.Key))
     .ToDictionary(p=> p.Key, p=> p.Value);

但如果你有很多条目,最好使用HashSet

var strings = new HashSet<string>(yourList);
var result= yourDictionary.Where(p=> strings.Contains(p.Key))
        .ToDictionary(p=> p.Key, p=> p.Value);

使用加入

 var query =
            from kvp in yourDictionary
            join s in yourList on kvp.Key equals s
            select new { kvp.Key, kvp.Value };

答案 4 :(得分:0)

借助以下有用功能

value.Trim( new Char[] { '\\', '\"'});

这里是IMO的最佳解决方案(每个密钥使用单个查找并且不引入闭包):

public static class Extensions
{
    public static KeyValuePair<TKey,TValue>? Find<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key)
    {
        TValue value;
        return source.TryGetValue(key, out value) ? new KeyValuePair<TKey, TValue>(key, value) : (KeyValuePair<TKey, TValue>?)null;
    }
}