按键过滤多维数组

时间:2017-06-14 21:46:18

标签: javascript arrays

我已经研究过在我看过的其他例子中使用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' },
]

6 个答案:

答案 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)

您可以先过滤具有optionsvariable键的对象,然后在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)

我不确定我是否真的喜欢我的答案,但似乎有效。

&#13;
&#13;
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;
&#13;
&#13;

答案 4 :(得分:1)

你可以做一些简短的事情。

&#13;
&#13;
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;
&#13;
&#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的所有元素。