以更高的效率将嵌套数组中的值添加到唯一列表中
Posted
技术标签:
【中文标题】以更高的效率将嵌套数组中的值添加到唯一列表中【英文标题】:Adding values from nested array into uniques list with better efficiency 【发布时间】:2020-03-24 02:30:18 【问题描述】:我正在使用 C#, 我得到了一个带有嵌套数组的文档 - 这是其数据结构的简化示例(作为 json) -
"property1": "...",
"property2": "...",
"lines": [
"lineProp1": "..",
"lineProp2": "..",
"nestedItems": [
"nestedValue": "12345"
,
"nestedValue": "1111"
]
]
我需要在此文档上运行,对于每一行,在其嵌套项目上运行,对于每个嵌套项目,将 nestedValue
添加到新列表中,并且仅针对唯一值(无重复)这样做。
最简单的方法就是这样做:
foreach(line in lines)
foreach(nestedItem in line.nestedItems)
check if nestedItem.nestedValue exists already exists in my new list,
if not add it.
我想知道是否有更有效的方法来做到这一点。 通过这个逻辑,我可能会有相当大的流量。
一点上下文: 我正在尝试提取一组文档 ID,然后通过 redis 缓存锁定这些资源,这样共享数据就不会同时得到处理。但我想让这种锁定/解锁机制的逻辑尽可能高效,这是其中的一部分。
【问题讨论】:
【参考方案1】:尝试在列表中查找重复项会花费很多。从HashSet 进行此类检查会更容易和更快(我将研究和更新检索时间 - 找不到硬值,但理论上它对于基于哈希的数据结构应该是 O(1) 和 O( N) 用于列表)。
警告:HashSet 不能排序,也不允许任何重复。
所以你可以保留代码并执行以下操作
foreach(line in lines)
foreach(nestedItem in line.nestedItems)
// Just add to the HashSet. If it exists it will not add it at all
返回:布尔值
如果元素被添加到 HashSet 对象,则为真;
如果元素已经存在则返回 false。
引用文档。
HashSet 类基于数学集合模型和 提供类似于访问密钥的高性能集合操作 字典或哈希表集合。在简单的 术语,HashSet 类可以被认为是一个 没有值的字典集合。
HashSet 集合未排序且不能包含重复项 元素。如果顺序或元素重复比 您的应用程序的性能,请考虑使用 List 类 与 Sort 方法一起使用。
仅转换为列表check this SO question
【讨论】:
也可以直接Add()
查看返回值。如果它返回false
,那么项目已经存在。【参考方案2】:
使用 Xpath Json 查询可以获得更好的性能。 以 Newtonsoft 库为例。
JObject json = JObject.Parse(jsonText);
var nestedValuesFromJson = json.SelectTokens("$.lines.nestedItems[:].nestedValue").Values<String>().Distinct();
完整示例
https://dotnetfiddle.net/FsbERA
【讨论】:
你测量过这个吗?还是只是猜测它可能会更好? 只是猜测。有可能找到一个不加载所有 json 的库来浏览它。它会导致更小的内存占用,尤其是对于非常大的 json以上是关于以更高的效率将嵌套数组中的值添加到唯一列表中的主要内容,如果未能解决你的问题,请参考以下文章