node.js - if 语句没有按预期工作

node.js - if statement not working as expected

这段 node.js 代码是 运行 针对 Spark History Server API。

它应该做的是找到名称与 uuid 和 return 仅该作业的 ID 传入的值相匹配的任何作业。

下面的代码实际上做的是,如果在任何作业名称中找到 uuid,则每个作业的 ID 都是 returned。

我认为这与我解析 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;
    }

reduce 是错误的方法。使用 findfilter。您甚至可以在已有的 filter 回调中执行此操作。然后你可以将 map 链接到它以获得每个匹配键的 id 属性 值:

var arrFound = Object.keys(json).filter(function(key) {
    console.log("gel json[key].name " + json[key].name);
    return json[key].name && json[key].name.includes(uuid);
}).map(function(key) {
    return json[key].id;
});

console.log (arrFound); // array of matched id values

另请注意,您对 indexOf 的使用是错误的。您需要将该值与 -1(未找到)进行比较。但是现在你可以使用 includes which returns a boolean.

请注意,在 Object.values 中,您列出的是对象而不是键,这在您的情况下更有趣:

var arrFound = Object.values(json).filter(function(obj) {
    console.log("gel obj.name " + obj.name);
    return obj.name && obj.name.includes(uuid);
}).map(function(obj) {
    return obj.id;
});

console.log (arrFound); // array of matched id values

虽然接受的答案提供了工作代码,但我觉得值得指出 reduce 是解决这个问题的好方法,对我来说比链接 filtermap:

const jobs = {
  1: {
    id: 1,
    name: 'job: 2a2912c5-9ec8-4ead-9a8f-724ab44fc9c7'
  },
  2: {
    id: 2,
    name: 'job: 30ea8ab2-ae3f-4427-8e44-5090d064d58d'
  },
  3: {
    id: 3,
    name: 'job: 5f8abe54-8417-4b3c-90f1-a7f4aad67cfb'
  },
  4: {
    id: 4,
    name: 'job: 30ea8ab2-ae3f-4427-8e44-5090d064d58d'
  }
}

const matchUUID = uuid =>
  (acc, job) => job.name.includes(uuid) ? [ ...acc, job.id ] : acc

const target = '30ea8ab2-ae3f-4427-8e44-5090d064d58d'
const matchTarget = matchUUID(target)

// [ 2, 4 ]
console.log(Object.values(jobs).reduce(matchTarget, []))

reduce 适用于这些类型的问题:获取更大、更复杂或完整的值,然后 将其减少 为您需要的数据。在大型数据集上,它也可以更有效,因为您只需要遍历集合一次。

如果您受 Node 版本限制或不想使用数组传播,这里有一个稍微多 'traditional' 的版本:

var result = Object.keys(jobs).reduce(
  function (acc, key) {
    if (jobs[key].name.includes(uuid)) {
      acc.push(jobs[key].id)
    }
    return acc
  },
  []
)

注意 Object.keys 的使用,因为 Object.values 是 ES2017,可能并不总是可用。 String.prototype.includes 是 ES2015,但如有必要,您始终可以使用 indexOf