尝试创建一个返回对象键的数组的函数,包括嵌套在其中的对象。我的代码如下所示:
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]
答案 0 :(得分:1)
您可以获取键并检查该值是否为对象,然后也可以使用此键。
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;
答案 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)
由于到目前为止发布的答案不会处理圆形物体,所以这就是:
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;
并且它不是递归的,因此它处理超过10,000级别的嵌套(这在今天的webdev中非常常见;)