我需要一个可以存储和检索具有多个潜在共享标记的对象的集合。我需要能够存储一个具有多个标记的对象,并检索所有具有一个或多个标记的对象。
我的第一个想法是让集合存储一个对象数组,以及一个Dictionary<string, Hashset<int>>,其中键是标记,值是标记应用到的索引。
但是,如果从集合中删除了一个对象,那么之后的所有索引现在都是不正确的。
我朝正确的方向走了吗?是否有一种我不知道的现有实现,或者对集合有帮助的标准方法?
发布于 2018-05-24 09:10:11
给定的
public class Something
{
public HashSet<string> Tags { get; set; }
}使用
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)));相当标准的内存方法
如果您想要更多类型,使用枚举(如果您不需要它们的动态)
发布于 2018-05-24 09:45:21
你朝正确的方向前进了。我想说的是,您应该在其他HashSet<T>实例中缓存公共交叉点,以便更快、更简单地处理事情。
但是,如果从集合中删除了一个对象,那么之后的所有索引现在都是不正确的。
虽然您可以构建一个反向字典Dictionary<int, HashSet<string>>,以便从标记索引中删除给定的对象,以避免在删除某个对象时迭代整个索引:
var tags = objectTagMap[394]
foreach(var tag in tags)
tagObjectMap[tag].Remove(394)不管怎样,如果你在考虑内存中的索引,为什么不使用Redis呢?Redis为您提供了散列(字典)、集和排序集(以及其他一些数据结构)。
这是一个非常简单的示例,说明如何在Redis中构建相同的策略:
# 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发布于 2018-05-24 09:41:12
为什么不使用:
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)));https://stackoverflow.com/questions/50505208
复制相似问题