指定日期范围按键值求和的最优JS对象数组结构选型与实现方法
结论
你的判断完全正确,dictionary1Ter 这种扁平的单条记录结构,远比第一种嵌套结构适合做筛选、聚合操作,代码写起来更简单,运行效率也更高。
第一种嵌套结构的问题
dictionary1Bis 天生就不适合做灵活查询:
- 日期被存成了对象的动态键,你要做日期范围判断时,必须先遍历对象的所有键,把嵌套在里面的物料记录一条条拆出来才能做后续处理,每次查询前都多了一步扁平化操作,平白增加冗余代码。
- 外层还套了一层没有实际作用的数组,访问数据时还要先取数组第0项,完全是多余的结构。
- 后续如果要加其他筛选维度,比如按数量区间、物料关键词筛选,你还是得把所有嵌套数据拍平,等于重复做无用功。
有没有更优的结构?
如果你的数据量不大(万条以内),dictionary1Ter 就是最优选择,维护成本最低,代码可读性最好。
如果是十万级以上数据、需要高频做同类聚合查询,可以提前构建双层索引结构做性能优化,索引结构参考:
// 双层索引:第一层按物料分组,第二层按日期存对应数量 const materialDateIndex = { "1_1$bolsa": { "2022-07-06": 23, "2022-07-07": 3, "2022-07-08": 10 }, "1_2$m3": { "2022-07-06": 2 }, "1_7$unidad": { "2022-07-06":4 } }
这种结构查询时不用遍历全量数据,直接定位到对应物料的日期集合做累加即可,性能最好,但缺点是新增、修改、删除数据时需要同步维护索引,小数据量下用这个属于过度设计。
补充:你用的
YYYY-MM-DD格式日期字符串,可以直接用>/<=这类比较运算符判断先后,不需要转成Date对象,非常方便。
基于dictionary1Ter的实现步骤
总共三步就能得到你要的结果:
- 筛选数据:遍历数组,捞出所有符合日期范围的条目,如果需要同时指定物料,直接在筛选条件里加对应判断即可
- 分组聚合:用一个临时对象按物料维度累加数量
- 格式转换:把聚合后的临时对象转成你需要的数组结构
对应代码如下:
// 1. 筛选符合条件的条目 const validRecords = dictionary1Ter.filter(item => { // 日期<=指定值,如果需要筛指定物料,追加判断 && item.material === "1_1$bolsa"即可 return item.date <= "2022-07-07" }) // 2. 按物料聚合数量 const countMap = {} validRecords.forEach(record => { if (!countMap[record.material]) countMap[record.material] = 0 countMap[record.material] += record.quantity }) // 3. 转成目标结果格式 const result = Object.entries(countMap).map(([material, quantity]) => ({ material, quantity }))
运行后得到的结果和你给出的预期完全一致:1_1$bolsa对应数量26,1_2$m3对应2,1_7$unidad对应4。
内容的提问来源于stack exchange,提问作者aragornii
相关产品推荐
相关产品推荐

