2015-09-17 217 views
1

我想要获取嵌套JS对象中的键的计数。我能够达到第一级,但我有点卡在我将如何挖入嵌套的对象并返回一个计数。嵌套对象中的键计数

var properties = { 
prop1: '', 
prop2: '', 
prop3: '', 
prop4: { 
    subProp1: '', 
    subProp2: '', 
    subProp3: { 
     subSubprop1: '' 
     } 
    } 
} 

var getCount = function (data) { 
var count = 0; 
for (var k in data) { 
    if (properties.hasOwnProperty(k)) { 
     ++count; 
    } 
} 
console.log("this is the count for level 0: " + count //returns 4); 
console.log("this is the count for level 1: " + count //should return 3); 
console.log("this is the count for level 2: " + count //should return 1); 
return count; 
} 
getCount(properties); 
+1

密切相关:什么是递归什么时候应该使用它?(http://stackoverflow.com/q/3021/464709) –

回答

6

你可以递归,如果属性是object

var properties = { 
 
     prop1: '', 
 
     prop2: '', 
 
     prop3: '', 
 
     prop4: { 
 
      subProp1: '', 
 
      subProp2: '', 
 
      subProp3: { 
 
       subSubprop1: '' 
 
      } 
 
     } 
 
    }, 
 
    count = []; 
 

 
// i suggest to use named function for recursion, because the name is used 
 
// inside the function. otherwise it is not safe, if the name does not 
 
// match the given name at assignment 
 
function getCount(data, level) { 
 
    level = level || 0; 
 
    count[level] = count[level] || 0; 
 
    for (var k in data) { 
 
     data.hasOwnProperty(k) && count[level]++; 
 
     typeof data[k] === 'object' && getCount(data[k], level + 1); 
 
    } 
 
} 
 

 
getCount(properties); 
 
document.write('<pre>' + JSON.stringify(count, 0, 4) + '</pre>');

奖励:一个版本内置了数以多功能风格

var properties = { 
 
     prop1: '', 
 
     prop2: '', 
 
     prop3: '', 
 
     prop4: { 
 
      subProp1: '', 
 
      subProp2: '', 
 
      subProp3: { 
 
       subSubprop1: '' 
 
      } 
 
     } 
 
    }; 
 

 
function f(o, l, r) { 
 
    l = l || 0;    
 
    return Object.keys(o).reduce(function (r, k) { 
 
     r[l] = (r[l] || 0) + 1; 
 
     typeof o[k] === 'object' && f(o[k], l + 1, r); 
 
     return r; 
 
    }, r || []); 
 
} 
 

 
document.write('<pre>' + JSON.stringify(f(properties), 0, 4) + '</pre>');

+0

对我的学习非常有帮助,thx尼娜! – ndesign11

2

这是做一个短期和哈克的方式:

var obj={a:0,b:1,c:{a:1,otherkeyb:'2:"":2\\',otherkey:{d:1,e:2}}} 
JSON.stringify(obj).match(/[^\\]":/g).length // return 8 

打破

这另一种解决方案将创建一个数组,告诉您在每个级别有多少项目

var count_in_level = [] 
var obj = { 
    a: 0, 
    b: { 
     ba: 1, 
     c: { 
      ca: 1, 
      cb: 2 
     } 
    } 
} 
function count(obj, level) { 
    var c = 0 
    if (typeof level == 'undefined') level = 1 
    if (!count_in_level[level]) count_in_level[level] = 0 
    if (typeof obj == 'object') { 
     for (var i in obj) { 
      if (typeof obj[i] == 'object') count(obj[i], level + 1) 
      c++; 
     } 
     count_in_level[level] += c 
    } 
} 
count(obj); 
console.log(count_in_level) // [1: 2, 2: 2, 3: 1] 

说明:等级1:2项,等级2:2等等EMS,3级:1项

+0

意志,通过嵌套层次分项列出?我认为reviver回调将工作,但再次与嵌套... – dandavis

+0

它会给你的总。对不起,你没有要求分解 – Aminadav

+0

我添加了一个函数来分解它 – Aminadav

1

如何使用Object.keys(如果可用[例如[不支持在IE < 9]中)并将计数存储在对象中,其中键是级别并且值是计数?

var properties = { 
    prop1: '', 
    prop2: '', 
    prop3: '', 
    prop4: { 
     subProp1: '', 
     subProp2: '', 
     subProp3: { 
      subSubprop1: '' 
     } 
    } 
}; 

function countKeysPerLevel(store, level, obj) { 
    var keys = Object.keys(obj); 
    var count = keys.length; 

    store[level] = (store[level] || 0) + count; 

    for (var i = 0; i < count; i++) { 
     var childObj = obj[keys[i]]; 
     if (typeof childObj === 'object') { 
      countKeysPerLevel(store, level + 1, childObj); 
     } 
    } 
} 

var result = {}; 
countKeysPerLevel(result, 0, properties); 
+0

我已经选择了一个答案,但upvoted这个,因为我真的很喜欢它。 – ndesign11