Node.js条件语句异常:Spark History Server API作业ID查询问题
问题描述
我最近在写Node.js代码对接Spark History Server API,想要实现的功能是:找到名称和传入的uuid完全匹配的作业,仅返回该作业的ID。但实际运行时出现了问题——只要任一作业的名称包含这个uuid,就会返回所有作业的ID。我猜测这可能和代码里的逻辑或者JSON处理方式有关,但不确定该怎么修改才能实现预期效果。
我的代码片段如下:
var arrFound = Object.keys(json).filter(function(key) { console.log("gel json[key].name" + json[key].name); return json[key].name; }).reduce(function(obj, key){ if (json[key].name.indexOf(uuid)) { obj = json[key].id; return obj; } })
问题分析
咱们来拆解下代码里的核心问题:
indexOf的判断逻辑完全反了:indexOf(uuid)返回的是uuid在名称中的起始位置——完全匹配时返回0,包含但非开头返回正数,不包含返回-1。但JavaScript里if(-1)会被判定为true(非0值都是真值),if(0)会被判定为false。这就导致:- 名称完全等于uuid时,条件不成立,不会返回ID;
- 名称包含uuid或完全不包含时,条件都成立,结果完全偏离预期。
reduce的用法不符合需求:reduce是用来累积结果的,但你这里的写法逻辑混乱,一旦进入分支就直接覆盖返回值,还没处理找不到匹配项的边界情况。filter没起到筛选作用:当前filter只是过滤掉名称为空的项,根本没帮你筛选匹配的作业。
修正后的代码
要实现“找到名称完全匹配uuid的作业,返回其ID”的需求,我们可以简化逻辑,先精准筛选再提取结果:
// 第一步:筛选出名称和uuid严格相等的作业 const matchedJobKeys = Object.keys(json).filter(key => { return json[key].name === uuid; // 用严格相等确保完全匹配 }); // 第二步:提取匹配作业的ID,没找到则返回null(可根据需求改默认值) const targetJobId = matchedJobKeys.length > 0 ? json[matchedJobKeys[0]].id : null;
如果你的json本身是数组格式(而非对象),代码可以更简洁:
const targetJob = json.find(job => job.name === uuid); const targetJobId = targetJob ? targetJob.id : null;
为什么这样改?
- 用**严格相等
===**替代indexOf,彻底避免“包含即匹配”的问题,只选中名称完全一致的作业; - 先筛选再提取的逻辑更清晰,也方便你处理“多个作业重名”的边界情况;
- 增加了找不到匹配项的处理,避免出现
undefined之类的意外结果。
内容的提问来源于stack exchange,提问作者pac
相关产品推荐
相关产品推荐

