首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >构建可通过标记检索的对象集合

构建可通过标记检索的对象集合
EN

Stack Overflow用户
提问于 2018-05-24 09:02:37
回答 4查看 144关注 0票数 2

我需要一个可以存储和检索具有多个潜在共享标记的对象的集合。我需要能够存储一个具有多个标记的对象,并检索所有具有一个或多个标记的对象。

我的第一个想法是让集合存储一个对象数组,以及一个Dictionary<string, Hashset<int>>,其中键是标记,值是标记应用到的索引。

  • 对于多个标记,获取索引集合的交集。
  • 若要从对象中移除标记,请从集合中移除该索引。

但是,如果从集合中删除了一个对象,那么之后的所有索引现在都是不正确的。

我朝正确的方向走了吗?是否有一种我不知道的现有实现,或者对集合有帮助的标准方法?

EN

回答 4

Stack Overflow用户

发布于 2018-05-24 09:10:11

给定的

代码语言:javascript
运行
复制
public class Something
{
   public HashSet<string> Tags { get; set; }
}

使用

代码语言:javascript
运行
复制
var list = new List<Something>
               {
                  new Something()
                     {
                        Tags = new HashSet<string>() { "tag1", "tag2" }
                     },
                  new Something()
                     {
                        Tags = new HashSet<string>() { "tag3", "tag4" }
                     }
               };

var searchList = new List<string> { "tag1", "tag4"};

var result = list.Where(x => x.Tags.Any(y => searchList.Contains(y)));

相当标准的内存方法

如果您想要更多类型,使用枚举(如果您不需要它们的动态)

票数 2
EN

Stack Overflow用户

发布于 2018-05-24 09:45:21

你朝正确的方向前进了。我想说的是,您应该在其他HashSet<T>实例中缓存公共交叉点,以便更快、更简单地处理事情。

但是,如果从集合中删除了一个对象,那么之后的所有索引现在都是不正确的。

虽然您可以构建一个反向字典Dictionary<int, HashSet<string>>,以便从标记索引中删除给定的对象,以避免在删除某个对象时迭代整个索引:

代码语言:javascript
运行
复制
var tags = objectTagMap[394]

foreach(var tag in tags) 
   tagObjectMap[tag].Remove(394)

不管怎样,如果你在考虑内存中的索引,为什么不使用Redis呢?Redis为您提供了散列(字典)、集和排序集(以及其他一些数据结构)。

这是一个非常简单的示例,说明如何在Redis中构建相同的策略:

代码语言:javascript
运行
复制
# Store objects as key-value pairs
set object:1 { "id": 1 }
set object:2 { "id": 2 }
set object:3 { "id": 3 }

// sadd (set add) to build the tag index
sadd tagA 1 2
sadd tagB 3

// sunion to get object ids from two or more tags
sunion tagA tagB

// mget (multiple get) to get object data from the result 
// of sunion concatenating "object:" with each object id
// This is a simple example. In a real world system you would use
// SCAN to avoid bottlenecks and being able to leverage paging.
mget object:1 object:2 object:3
票数 1
EN

Stack Overflow用户

发布于 2018-05-24 09:41:12

为什么不使用:

代码语言:javascript
运行
复制
Dictionary<List<string>, HashSet<int>> taggedDict = new Dictionary<List<string>, HashSet<int>>();
var searchList = new List<string> { "tag1", "tag4" };
var keys = taggedDict.Keys.Where(x => x.Any(y => searchList.Contains(y)));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50505208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档