以递归方式返回嵌套键数组javascript

时间:2018-03-08 12:34:44

标签: javascript object recursion nested

尝试创建一个返回对象键的数组的函数,包括嵌套在其中的对象。我的代码如下所示:

function keyCount(obj, arr) {
  if (arr == undefined){
    arr = []
  }
  let keys = Object.keys(obj);
  let length = keys.length;
  for (i = 0; i <= length; i++){
    if (Object.keys(obj)[i] !== undefined){
      arr.push(Object.keys(obj)[i]);
    }
  }
  for (i = 0; i <= length; i++){
    if (typeof(obj[Object.keys(obj)[i]]) === "object" && obj[Object.keys(obj)[i]] !== null && Object.keys(obj)[i] !== undefined){
      let nestedobj = obj[Object.keys(obj)[i]];
      keyCount(nestedobj,arr)
    }
  }
  return (arr);
}

这将返回第一级键和一个嵌套对象的键,但在第一次递归调用后退出该函数。有没有办法绕过这个或更好的方式来格式化代码?提前谢谢!

编辑:   数据期望:

let obj1 = {
1:"a",
2:{
  3: "b",
  4: "c"},
5:{
  6:"d",
  7: "e",
  8: {
    9: "f",
    10: "g"},
    11:{
      12:"h",
      13: "i"
      }
    }
  };

应该返回:

[1,2,5,3,4,6,7,8,9,10,11,12,13]

但只返回:

[1,2,5,3,4]

4 个答案:

答案 0 :(得分:1)

您可以获取键并检查该值是否为对象,然后也可以使用此键。

&#13;
&#13;
function getKeys(object) {
    return Object
        .keys(object)
        .reduce((r, k) => r.concat(k, object[k] && typeof object[k] === 'object' ? getKeys(object[k]) : []), []);
}


var object = { 1: "a", 2: { 3: "b", 4: "c" }, 5: { 6: "d", 7: "e", 8: { 9: "f", 10: "g" }, 11: { 12: "h", 13: "i" } } };

console.log(getKeys(object));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您的代码存在各种问题。最重要的是i is implicitly global,它会导致递归调用改变循环条件。你很幸运,你没有得到无限循环......

function keyCount(obj, arr) {
  "use strict";
//^^^^^^^^^^^^^ prevent mistakes with forgotten declarations
  if (arr == undefined){
    arr = []
  }
  const keys = Object.keys(obj);
//^^^^^ prefer const over let when you don't assign
  const length = keys.length;
  for (let i = 0; i < length; i++) {
//                 ^^^ don't use <=
//     ^^^ i needs to be a local variable!
    // if (keys[i] !== undefined)
//  ^^^ no longer necessary when having fixed the loop
      arr.push(keys[i]);
//             ^^^^ don't call Object.keys again
  }
  for (let i = 0; i < length; i++) {
//     ^^^          ^ same as above
    const nestedobj = obj[keys[i]]; // move this up here
//                        ^^^^ same as above
    if (typeof nestedobj === "object" && nestedobj !== null  ) {
//            ^         ^ typeof is not a function          ^ same as above
      keyCount(nestedobj, arr);
    }
  }
  return arr;
}

答案 2 :(得分:0)

let obj1 = {
1:"a",
2:{
  3: "b",
  4: "c"},
5:{
  6:"d",
  7: "e",
  8: {
    9: "f",
    10: "g"},
    11:{
      12:"h",
      13: "i"
      }
    }
  };

var keyArray = [];

function getKeys(obj){
  // get the keys from the current level
  var keys = Object.keys( obj );
  // iterate through each key, add it to our keyArray[]
  for( var i=0, x=keys.length; i<x; i++ ){
    keyArray.push( keys[i] );
    // if there is another array/object (instead of a
    // value) send that section of the obj back into
    // the function
    if( obj[keys[i]].constructor === Object ){
      getKeys( obj[keys[i]] );
    }
  }
}

getKeys(obj1);

//Should return:
//console.log( 'expected', [1,2,5,3,4,6,7,8,9,10,11,12,13] );
console.log( 'result: ', keyArray.join(',') );

答案 3 :(得分:0)

由于到目前为止发布的答案不会处理圆形物体,所以这就是:

&#13;
&#13;
function getKeys(obj) {
    let seen = new WeakSet(),
        keys = new Set(),
        queue = [obj];

    while (queue.length) {
        let obj = queue.shift();
        
        if (!obj || typeof obj !== 'object' || seen.has(obj))
            continue;
        
        seen.add(obj);
        
        for (let [k, v] of Object.entries(obj)) {
            keys.add(k);
            queue.push(v);
        }
    }

    return [...keys];
}

//

weirdo = {a: 1, b: 2, c: 3}
weirdo.self = weirdo;
console.log(getKeys(weirdo))
&#13;
&#13;
&#13;

并且它不是递归的,因此它处理超过10,000级别的嵌套(这在今天的webdev中非常常见;)