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
是错误的方法。使用 find
或 filter
。您甚至可以在已有的 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
是解决这个问题的好方法,对我来说比链接 filter
和 map
:
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
。
这段 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
是错误的方法。使用 find
或 filter
。您甚至可以在已有的 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
是解决这个问题的好方法,对我来说比链接 filter
和 map
:
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
。