递归列出嵌套对象键

时间:2019-12-03 21:04:30

标签: javascript node.js

我有一个这样的嵌套对象:

  options = {
    religous: {
      kosher: {
        value: 'Kosher',
        chosen: false
      },
      halal: {
        value: 'Halal',
        active: false
      },
    },
    vegan: {
      value: 'Vegan',
      active: false
    }
  }

它包含大小不同的嵌套对象。我想要一个包含任何value属性值的Array。因此,对于上述对象,所需的输出将是:

['Kosher', 'Halal', 'Vegan']

顺序并不重要。 我试图像这样递归地这样做:

  getListOfLabels = obj => {
    const lst = []
    for (let key in obj) {
      if (obj[key].value) lst.push(obj[key].value)
      else return getListOfLabels(obj[key])
    }
    return lst
  }

但我一直收到 RangeError:超出了最大调用堆栈大小错误。

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

for...in循环分配key。要获取值,请使用obj[key]。如果keyvalue,请添加到lst,如果是对象,请在其上调用getListOfLabels,然后将结果分散到lst.push()中:

const options = {"religous":{"kosher":{"value":"Kosher","chosen":false},"halal":{"value":"Halal","active":false}},"vegan":{"value":"Vegan","active":false}}


const getListOfLabels = obj => {
  const lst = []
  
  for (let key in obj) {
    const val = obj[key] // get the value
    if (key === 'value') lst.push(val) // if the key name is "value" push to lst
    else if(typeof val === 'object') lst.push(...getListOfLabels(val)) // if type of value is object, iterate it with getListOfLabels and push the results into lst
  }
  
  return lst
}

const result = getListOfLabels(options)

console.log(result)

答案 1 :(得分:1)

您可以采用递归方法,并检查对象是否包含value键。

function getValues(object, key) {
    if (key in object) return [object[key]];
    
    return Object.values(object).reduce((r, v) => {
        if (v && typeof v === 'object') r.push(...getValues(v, key));
        return r;
    }, []);
}

var options = { religous: { kosher: { value: 'Kosher', chosen: false }, halal: { value: 'Halal', active: false } }, vegan: { value: 'Vegan', active: false } };

console.log(getValues(options, 'value'));

答案 2 :(得分:0)

这是使用reduce :-D的简洁方法。

const getValues = options => Object.values(options)
  .reduce((acc, optionObj) => (
    optionObj.value ? [ ...acc, optionObj.value ] : [
    ...acc,
    ...Object.values(optionObj).reduce((arr, { value }) => ([ ...arr, value ]), [])
  ]), [])
相关问题