递归返回对象和嵌套对象键的数组

时间:2019-06-04 18:12:49

标签: javascript object recursion

此刻我正在学习递归,并且已经从数字,字符串和数组转移到在对象上使用它……我正在尝试找出将对象作为参数并收集键的最佳方法对象和所有嵌套对象组成一个数组

我可以不使用递归来返回单个对象的对象键。因此,我试图将变量创建为空数组,然后使用for循环遍历对象,如果“ i”是对象,则将对象键推入数组变量并返回它。不幸的是,这行不通。

我想要以下内容:

{lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}}

要返回:

[lamp, candle, pillow, big, small, bathroom, toilet, shower, shampoo, conditioner]

希望这足以说明问题,如果不可以,请告诉我

我尝试了以下操作:

function(obj) {
let keysArray = [];
for (let i = 0, i < obj.length, i++)
if (obj[i] === typeOf object) {
keysArray.push(obj[i].keys);
}
return keysArray
}

4 个答案:

答案 0 :(得分:2)

您可以编写如下的递归函数

let obj = {lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}};

function getKeys(o) {
  let result = [];
  for (let key in o) {
    result.push(key);
    if(o[key] && typeof o[key] === "object") result.push(...getKeys(o[key]));
  }
  return result;
}

console.log(getKeys(obj));

答案 1 :(得分:1)

  • 您需要使用for...in遍历对象。 for循环用于数组
  • obj[i] === typeOf object不正确。它应该是typeof obj[key] === "object"
  • 如果嵌套属性是对象,则需要递归调用函数和push的{​​{1}}键

keysArray

仅供参考:function getKeys(obj) { let keysArray = []; for (let key in obj) { keysArray.push(key); if (typeof obj[key] === "object") keysArray.push(...getKeys(obj[key])) } return keysArray } const input={lamp:2,candle:2,pillow:{big:2,small:4},bathroom:{toilet:1,shower:{shampoo:1,conditioner:2}}} console.log(getKeys(input))是“对象”。因此,如果任何属性为null,则上面的代码将引发错误。因此,可以使用typeof null。对于除null以外的所有对象都是如此

此外,如果支持flatMap,则可以执行类似的操作

Object(obj[k]) === obj[k]

答案 2 :(得分:1)

怎么样:

const keys = obj => Object.keys(obj).reduce((acc, key) => {
  acc.push(key);
  return (obj[key] !== null && typeof obj[key] === 'object') // Avoid evaluating null as an object
    ? acc.concat(keys(obj[key])) 
    : acc;
}, []);

用法:

keys({foo: 1, bar: {foobar: 2}}); // Outputs ['foo', 'bar', 'foobar']

答案 3 :(得分:0)

一个非常好的生成器用例。这是一个示范-

const data =
  {lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}}

const keys = function* (o = {}) {
  if (Object(o) === o)
    for (const [k, v] of Object.entries(o)) {
      yield k
      yield* keys(v)
    }
}
  
console.log(Array.from(keys(data)))
// [lamp, candle, pillow, big, small, bathroom, toilet, shower, shampoo, conditioner]

另一种解决方案是使用Array.prototype.flatMap-

const data =
  {lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}}

const keys = (o = {}) =>
  Object(o) === o
    ? Object.entries(o).flatMap(([ k, v ]) =>
        [ k, ...keys(v) ]
      )
    : []
  
console.log(keys(data))
// [lamp, candle, pillow, big, small, bathroom, toilet, shower, shampoo, conditioner]