我有一个包含所有用户及其年龄的字典。
Dictionary<string,int> AllUsers;
我有一个特定用户列表。
List<String> Users;
我希望筛选出字典 AllUsers 的那些用户名在 SpecificUsers 列表中的用户。我已经手动循环做了一些事情,但我希望使用 linq 表达式。不过我对它们不是很熟悉。非常感谢您的帮助。
var newdict = AllUsers.Where(x => Users.Contains(x.Key))
.ToDictionary(val => val.Key, val => val.Value);
它将创建一个新的字典(因为linq是用于查询而不是更新),其中包含来自字典且在Users
列表中的所有用户。您需要使用ToDictionary
来实际生成字典。
编辑: 正如@Rawling所说,更有效的方法是在字典上过滤而不是在列表上。实现该解决方案的方法在@Luaan的答案中(我不会复制它,因为有些人这样做)
O(1)
查找的集合,然后在O(n)
查找的集合上调用Contains
方法? - Rawling您可以过滤用户
:
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])
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
结果集中只有出现在两个集合中的名称才会被包含。
有多种方法可以做到这一点
您可以使用 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);
使用JOIN
var query =
from kvp in yourDictionary
join s in yourList on kvp.Key equals s
select new { kvp.Key, kvp.Value };
借助以下有用的函数的帮助
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;
}
}
这里是我认为最优解(每个键只使用单一查找,不引入闭包):
var filteredUsers = Users.Select(AllUsers.Find)
.Where(item => item.HasValue)
.ToDictionary(item => item.Value.Key, item => item.Value.Value);
foreach
)。此外,ReSharper可以为您完成此操作,并成为一个很好的学习工具。 - Yuck