我有一本字典,其中包含所有具有相应年龄的用户。
Dictionary<string,int> AllUsers;
我有一个特定用户列表。
List<String> Users;
我想仅使用AllUsers
列表中名称相同的用户过滤第一个字典SpecificUsers
。
我已经使用循环手动完成了某些操作,但我想使用linq表达式,但我对它们并不是很熟悉。
提前感谢您的帮助
答案 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;
}
}