【问题标题】:How to lookup inner hashset in dictionary and return key value in c#?如何在字典中查找内部哈希集并在 C# 中返回键值?
【发布时间】:2020-02-05 17:00:26
【问题描述】:

我正在尝试将 signalR 组存储在字典中>

但是我不知道如何在 HashSet 中查找字符串值并返回键字符串?

    var dict = new Dictionary<string, HashSet<string>>();
    dict["GroupA"] = ["user1","user2","user3"];
    dict["GroupB"] = ["user3", "user4"];
    dict["GroupC"] = ["user4","user5","user6"];

我想查找“user3”,它应该返回 ["GroupA","GroupB"]。我不知道如何在 c# 中使用字典。 我有大约 20k 组和许多用户。它是否使用单例模式处理过多的组和用户(存储在内存中)?

希望有人帮助我提供一个可行的示例。我是这里的初学者。谢谢!

【问题讨论】:

  • "我想查找 "user3",它应该返回 ["GroupA","GroupB"]。"如果你想按组查找成员,你应该按组存储成员,按成员分组!。
  • 我正在努力做到这一点:大约 20k 左右的组太多,用户会订阅他们的列表。用户登录并发送组 ID 列表。 Hub 会将此用户添加到组中。没关系。但是如果这个用户发送一个新的组列表,那么集线器应该从所有加入的组中删除这个用户,并将这个用户添加到这个新的组 id 列表中进行订阅。你有解决这个问题的想法吗?谢谢@AKX
  • 对于一个简单的解决方案(对于 20k 组可能会占用一些内存),同时存储“username-to-groupnames”和“groupname-to-usernames”字典。
  • 它的倍数太多了,不是吗?将它们存储在 sql 中并再次从那里获取是个好主意吗?因为,对于 5k 用户来说,20.000x5.000 = 100m 所以这对于内存来说真的是巨大的数据,不是吗? 20k 也可能超过 50k
  • 您没有提到 SQL 是一个选项。如果是,那么一定要这样做——SQL 数据库擅长这种事情。 SELECT group_name FROM user_groups WHERE user_name='foo'.

标签: c# dictionary .net-core hashset


【解决方案1】:

您需要对字典进行迭代,并获取所有指向包含您要查找的值的哈希集的键:

var matches = dict.Where(kvp => kvp.Value.Contains("user3"));

说明:
您要求提供所有键值对,其中 Value(我们知道它是 Hashset 类型)包含您要查找的字符串。

更新:仅从键值对中获取键,我相信您可以这样做:

var matches = dict.Where(kvp => kvp.Value.Contains("user3")).Select(kvp => kvp.Key);

进一步思考:如果您的用例总是优先按用户查找,也许您应该反转字典:将用户名作为键,值将是用户所属的组。这样,查找用户的所有组将是 O(1)。

【讨论】:

  • 除了 OP 拥有的所有“~20k”组的 O(n) 之外,我们是否还需要将 KVP 映射到其他东西?
  • 如果有人有更好的解决方案来映射映射器或列表中的组和用户。我很乐意在这里听到。
【解决方案2】:

答案将视情况而定:

  • 如果 SQL 是一个选项,则在加载前在 SQL 中执行此操作。总体而言,它的效率更高。
  • 如果您总是需要按用户搜索,请翻转字典,按成员列出组。
  • 如果查找发生在服务器端,我会使用两个字典:1 个成员一个组,1 个成员一个组。这会使内存使用量翻倍,但如果您可以让这些单例为来自相同实例的所有客户端提供服务,那么影响应该是有限的。
  • 如果查找发生在客户端而不是只为他们所属的每个用户加载一个迷你组列表(来自 SQL 或来自服务器端单例)在这种情况下无需搜索任何组以查找其他成员我会想象的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-13
    • 2011-05-21
    • 2014-05-18
    • 1970-01-01
    • 2015-07-09
    • 2016-08-12
    • 2017-08-04
    • 1970-01-01
    相关资源
    最近更新 更多