我已经研究过在我看过的其他例子中使用reduce,filter和map,但我不确定它们是否适合我的用例。假设我有以下多维数组:
const variableOpts = [
{ id: -1, value: 'Select Variable' },
{ id: 1,
value: 'Patient',
options: [
{ id: 2, value: 'First Name', variable: '{first_name}', variableValue: 'Billy' },
{ id: 3, value: 'Last Name', variable: '{last_name}', variableValue: 'Bob' },
{ id: 4, value: 'Office Location', variable: '{office_location}', variableValue: 'Mount Pleasant' },
],
},
{ id: 5, value: 'Another option', variable: '{another_option}', variableValue: 'Test' },
];
我想要做的是抓取包含variable
键的任何对象,无论它们是顶级项目还是项目内;就像options
数组一样。任何帮助将不胜感激。谢谢!
理想情况下,我想拥有一个包含所有内容的数组,因此我可以循环遍历它们,如下所示:
[
{ id: 2, value: 'First Name', variable: '{first_name}', variableValue: 'Billy' },
{ id: 3, value: 'Last Name', variable: '{last_name}', variableValue: 'Bob' },
{ id: 4, value: 'Office Location', variable: '{office_location}', variableValue: 'Mount Pleasant' },
{ id: 5, value: 'Another option', variable: '{another_option}', variableValue: 'Test' },
]
答案 0 :(得分:2)
使用递归,您可以循环遍历数组,检查键variable
的每个值,如果找到,则将其附加到一个好的值数组。然后检查是否有选项键,如果找到,递归检查每个选项。像这样:
const variableOpts = [{ id: -1, value: 'Select Variable' }, { id: 1, value: 'Patient', options: [{ id: 2, value: 'First Name', variable: '{first_name}', variableValue: 'Billy' }, { id: 3, value: 'Last Name', variable: '{last_name}', variableValue: 'Bob' }, { id: 4, value: 'Office Location', variable: '{office_location}', variableValue: 'Mount Pleasant' }, ], }, { id: 5, value: 'Another option', variable: '{another_option}', variableValue: 'Test' }, ];
function findVariable(arr){
//output variable
var out = [];
//loop over array
arr.forEach(function(a){
//if has variable key, add it to output
if(a.variable){
out.push(a);
}
//if has options, recurse and concat any with variable to output
if(Array.isArray(a.options)){
out = out.concat(findVariable(a.options));
}
});
//return the output
return out;
}
console.log(findVariable(variableOpts));

答案 1 :(得分:2)
您可以先过滤具有options
或variable
键的对象,然后在for
循环中对结果进行标准化...
const variableOpts = [{id: -1, value: 'Select Variable' }, {id: 1, value: 'Patient', options: [{id: 2, value: 'First Name', variable: '{first_name}', variableValue: 'Billy' }, {id: 3, value: 'Last Name', variable: '{last_name}', variableValue: 'Bob' }, {id: 4, value: 'Office Location', variable: '{office_location}', variableValue: 'Mount Pleasant' }]}, {id: 5, value: 'Another option', variable: '{another_option}', variableValue: 'Test' }];
const tempOpts = variableOpts.filter(function(obj){
return (obj.options && Array.isArray(obj.options)) || obj.variable;
});
const finalOpts = [];
for(let i = 0; i < tempOpts.length; i++){
let currentOpt = tempOpts[i];
if(currentOpt.options)
{
for(let i = 0; i < currentOpt.options.length; i++){
finalOpts.push(currentOpt.options[i]);
}
}else
{
finalOpts.push(currentOpt);
}
}
console.log(finalOpts);
答案 2 :(得分:1)
您可以在填充结果数组时进行递归检查:
const variableOpts=[{id:-1,value:'Select Variable'},{id:1,value:'Patient',options:[{id:2,value:'First Name',variable:'{first_name}',variableValue:'Billy'},{id:3,value:'Last Name',variable:'{last_name}',variableValue:'Bob'},{id:4,value:'Office Location',variable:'{office_location}',variableValue:'Mount Pleasant'}]},{id:5,value:'Another option',variable:'{another_option}',variableValue:'Test'}];
var findObjects = function() {
var isArray = function(a) {
return a.map == [].map;
};
var isObject = function(o) {
return Object(o) === o;
};
var result = [];
var stepThrough = function(obj) {
if (isArray(obj))
return obj.forEach(stepThrough);
if (isObject(obj)) {
for (var key in obj)
if (isArray(obj[key])) {
stepThrough(obj[key]);
delete obj[key];
}
if (obj.hasOwnProperty('variable'))
result.push(obj);
}
};
for (var i = 0; i < arguments.length; i++) {
stepThrough(arguments);
}
return result;
};
console.log( findObjects(variableOpts) );
答案 3 :(得分:1)
我不确定我是否真的喜欢我的答案,但似乎有效。
const variableOpts = [{ id: -1, value: 'Select Variable' }, { id: 1, value: 'Patient', options: [{ id: 2, value: 'First Name', variable: '{first_name}', variableValue: 'Billy' }, { id: 3, value: 'Last Name', variable: '{last_name}', variableValue: 'Bob' }, { id: 4, value: 'Office Location', variable: '{office_location}', variableValue: 'Mount Pleasant' },], }, { id: 5, value: 'Another option', variable: '{another_option}', variableValue: 'Test' },];
let result = [];
let checkArrayEntry = obj => {
if (obj.hasOwnProperty('variable')) result.push(obj);
Object.keys(obj).filter(prop => obj[prop] instanceof Array).forEach(entry => obj[entry].forEach(checkArrayEntry));
};
variableOpts.forEach(checkArrayEntry);
console.log(result);
&#13;
答案 4 :(得分:1)
你可以做一些简短的事情。
const variableOpts = [{ id: -1, value: 'Select Variable'},{id: 1,value: 'Patient',options: [{id: 2,value:'First Name', variable: '{first_name}',variableValue: 'Billy'},{id: 3,value: 'Last Name',variable: '{last_name}',ariableValue: 'Bob'},{ id: 4, value: 'Office Location',variable: '{office_location}',variableValue: 'Mount Pleasant'},],},{id: 5,value: 'Another option',variable: '{another_option}',variableValue: 'Test'},];
var val = variableOpts.filter(item => item.id != -1)
val = val.reduce((a, b) => a.concat(b.options || b), [])
console.log(val);
&#13;
答案 5 :(得分:0)
如果您想使用地图的功能解决方案,您可以先定义一个展平函数
function flatten(arr) {
return [].concat.apply([], arr)
}
function filterArray(arr, f) {
if(!(arr instanceof Array)) return [];
return flatten(arr.map(elem =>
(f(elem)?[elem]:[]).concat(filterArray(elem["options"], f))
));
}
然后你可以写例如。
console.log(filterArray(variableOpts, elem => elem["variable"]&&elem["variable"].indexOf("name")>=0));
获取name
属性中某处包含字符串variable
的所有元素。