我需要一个javascript递归函数,当key和JavaScript对象传递给这个函数时返回一个值数组。
请注意,嵌套的JavaScript对象具有未知深度。该函数工作正常,但它返回重复。
function getValuesByKey(object, key) {
var values = [];
recursiveFx(object);
function recursiveFx(object) {
for (var property in object) {
if (object.hasOwnProperty(property)) {
if (typeof object[property] == "object") {
recursiveFx(object[property]);
} else {
//found a property which is not an object
try {
if (isDefined(object[key])) {
console.log('Here is the value that is to be pushed',object[key]);
values.push(object[key]);
}
} catch (e) {
}
}
}
}
}
return values;
}
这是isDefined辅助函数
function isDefined(variable) {
try {
if (typeof(variable) !== 'undefined') return true;
} catch (e) {
return false;
}
}
以下是JavaScript对象的示例:
{
"children": [{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "1",
"children": [{
"id": "10",
"index": "0",
"text": "Grandstream GXP-21XX"
}, {
"id": "11",
"index": "1",
"text": "Polycom Soundstation/Soundpoint"
}, {
"id": "23",
"parentid": "8",
"index": "2",
"text": "New Polycom",
"children": [{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "1",
"children": [{
"id": "10",
"index": "0",
"text": "Grandstream GXP-21XX"
}, {
"id": "11",
"index": "1",
"text": "Polycom Soundstation/Soundpoint"
}, {
"id": "23",
"index": "2",
"text": "New Polycom"
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "0",
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "2",
"children": [{
"id": "9",
"index": "0",
"text": "Sonicwall"
}, {
"id": "12",
"index": "1",
"text": "Cisco"
}]
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "0",
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "2",
"children": [{
"id": "9",
"index": "0",
"text": "Sonicwall"
}, {
"id": "12",
"index": "1",
"text": "Cisco"
}]
}]}]};
当我运行此getValuesByKey(jsonObj, 'id');
时,我得到以下数组:
["5", "5", "5", "5", "10", "10", "10", "11", "11", "11", "23", "23", "23", "23", "5", "5", "5", "5", "10", "10", "10", "11", "11", "11", "23", "23", "23", "6", "6", "6", "6", "7", "7", "7", "7", "9", "9", "9", "12", "12", "12", "6", "6", "6", "6", "7", "7", "7", "7", "9", "9", "9", "12", "12", "12"]
请注意,5已被返回4次而不是2次
答案 0 :(得分:7)
您每次通过循环检查对象属性是否存在key
。因此,您获得的值与对象上的属性一样多。所以:
function getValuesByKey(object, key) {
var values = [];
recursiveFx(object);
function recursiveFx(object) {
if (key in object) values.push(object[key]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for (var property in object) {
if (object.hasOwnProperty(property)) {
if (typeof object[property] == "object") {
recursiveFx(object[property]);
}
}
}
}
return values;
}
JSON.stringify
与替换者无论如何,您可以使用
更轻松地完成此操作function getValuesByKey(object, key) {
var values = [];
JSON.stringify(object, function(k, v) {
if (k === key) values.push(v);
return v;
});
return values;
}
这使用replacer
参数JSON.stringify
拦截每个键值对。字符串化的值本身我们不需要扔掉。
答案 1 :(得分:2)
只是一个递归的想法:
var data = { "children": [{ "id": "5", "parentid": "0", "text": "Device Guides", "index": "1", "children": [{ "id": "10", "index": "0", "text": "Grandstream GXP-21XX" }, { "id": "11", "index": "1", "text": "Polycom Soundstation/Soundpoint" }, { "id": "23", "parentid": "8", "index": "2", "text": "New Polycom", "children": [{ "id": "5", "parentid": "0", "text": "Device Guides", "index": "1", "children": [{ "id": "10", "index": "0", "text": "Grandstream GXP-21XX" }, { "id": "11", "index": "1", "text": "Polycom Soundstation/Soundpoint" }, { "id": "23", "index": "2", "text": "New Polycom" }] }, { "id": "6", "parentid": "0", "text": "Pre-Sales Evaluation", "index": "0", "children": [] }, { "id": "7", "parentid": "0", "text": "Router Setup Guides", "index": "2", "children": [{ "id": "9", "index": "0", "text": "Sonicwall" }, { "id": "12", "index": "1", "text": "Cisco" }] }] }, { "id": "6", "parentid": "0", "text": "Pre-Sales Evaluation", "index": "0", "children": [] }, { "id": "7", "parentid": "0", "text": "Router Setup Guides", "index": "2", "children": [{ "id": "9", "index": "0", "text": "Sonicwall" }, { "id": "12", "index": "1", "text": "Cisco" }] }] }] };
function getValuesByKey(object, key) {
var values = [];
function r(obj) {
Object.keys(obj).forEach(function (k) {
if (Array.isArray(obj[k])) {
obj[k].forEach(r);
return;
}
if (typeof obj[k] === 'object') {
r(obj[k]);
return;
}
k === key && !~values.indexOf(obj[k]) && values.push(obj[k]);
});
}
r(object);
return values;
}
document.write('<pre>' + JSON.stringify(getValuesByKey(data, 'id'), 0, 4) + '</pre>');
答案 2 :(得分:0)
好的我明白了,你的代码中有一个错误。测试if(isDefined(object [key])){
时应测试该键=== property否则,只要在另一个属性中检查具有该值的对象时,您只需添加匹配值(如果明确的话):)