如何从嵌套JSON中精准提取值并完成指定条件比较(JavaScript)
问题描述
我的JSON文件结构固定但值可变,需要实现以下逻辑:
- 从
DecisionHistory数组末尾开始向前查找 - 找到第一个满足以下两个条件的元素时,返回
true并停止查找:AppStatus属于["Approved", "Auto Approved", "Return"]- 该元素的
DataElements中,Name为"Payments"和"Term"的Value不相等
- 希望避免使用嵌套for循环,改用
filter/map/reduce或其他更简洁的数组方法实现 - 已将
main函数导出至app.js用于断言测试,JSON文件存于VS Code资源文件夹
解决方案
可以使用ES2022新增的Array.prototype.findLast()方法,它原生支持从数组末尾开始遍历,找到第一个匹配项后立即终止,完全符合你的需求。结合reduce将数组转为键值对,无需嵌套循环:
// 假设导入的JSON数据为data对象 function checkDecisionCondition(data) { // 用Set存储目标状态,提升查找效率 const targetStatuses = new Set(["Approved", "Auto Approved", "Return"]); // 从DecisionHistory末尾开始查找符合条件的元素 const matchedItem = data.DecisionHistory.findLast(item => { // 先判断状态是否符合,不符合直接跳过 if (!targetStatuses.has(item.AppStatus)) return false; // 将DataElements转为键值对对象,方便快速取值 const dataMap = item.DataElements.reduce((map, elem) => { map[elem.Name] = elem.Value; return map; }, {}); // 判断Payments和Term的Value是否不等 return dataMap.Payments !== dataMap.Term; }); // 找到匹配项返回true,否则返回false return !!matchedItem; } // 导出函数供app.js的断言测试使用 module.exports = checkDecisionCondition;
关键细节说明
findLast()的优势:无需手动反转数组,原生从末尾遍历,找到匹配项后立即停止,性能更优- Set优化状态校验:
Set.has()的查找效率远高于数组includes(),适合状态数量较多的场景 - reduce转换数据结构:把
DataElements数组转为键值对,避免重复遍历数组查找指定Name,提升代码可读性和执行效率 - 短路逻辑:先校验
AppStatus,不满足条件直接跳过后续处理,减少不必要的计算
兼容旧环境的替代方案
如果运行环境不支持ES2022的findLast(),可以通过复制并反转数组的方式实现:
function checkDecisionCondition(data) { const targetStatuses = new Set(["Approved", "Auto Approved", "Return"]); // 复制原数组并反转,从原末尾开始查找 const matchedItem = [...data.DecisionHistory].reverse().find(item => { if (!targetStatuses.has(item.AppStatus)) return false; const dataMap = item.DataElements.reduce((map, elem) => { map[elem.Name] = elem.Value; return map; }, {}); return dataMap.Payments !== dataMap.Term; }); return !!matchedItem; }
内容的提问来源于stack exchange,提问作者Cooliozar
相关产品推荐
相关产品推荐

