我有一个可能包含对象的对象(反过来可能包含对象,也可能不包含无穷大的对象等),其中包含字符串,如下所示:
var obj = {
"foo": "hello",
"bar": "hi",
"test": {
"foo": "foo"
"bar": {
"test": "hi",
"hello": "howdy"
}
}
}
我想要做的是计算整个obj
对象及其子对象中的字符串数。在这个例子中,正确的答案是5。
关于计算此站点上对象中的键的众多主题都建议使用.hasOwnProperty
的循环或新的Object.keys(obj)
方式,但这些都不是递归的,并且它们都计算在内孩子反对自己。
实现这一目标的最佳方法是什么?
答案 0 :(得分:6)
您可以创建循环嵌套对象并返回计数的递归函数。
var obj = {
"foo": "hello",
"bar": "hi",
"test": {
"foo": "foo",
"bar": {
"test": "hi",
"hello": "howdy"
}
}
}
function countS(data) {
var c = 0;
for (var i in data) {
if (typeof data[i] == 'object') c += countS(data[i]);
if (typeof data[i] == 'string') c += 1
}
return c;
}
console.log(countS(obj))

答案 1 :(得分:1)
这是函数式编程样式的ES6函数:
function countPrimitives(obj) {
return +(Object(obj) !== obj) ||
Object.keys(obj).reduce( (cnt, key) => cnt + countPrimitives(obj[key]), 0 );
}
var obj = {
"foo": "hello",
"bar": "hi",
"test": {
"foo": "foo",
"bar": {
"test": "hi",
"hello": "howdy"
}
}
};
console.log(countPrimitives(obj));
实际上,这也会计算其他原始值,包括数字和布尔值,......:任何不是嵌套对象的东西。
答案 2 :(得分:1)
您可以使用Array#reduce
迭代密钥并检查对象。
function getCount(object) {
return Object.keys(object).reduce(function (r, k) {
return r + (object[k] && typeof object[k] === 'object' ? getCount(object[k]) : 1);
}, 0);
}
var obj = { foo: "hello", bar: "hi", test: { foo: "foo", bar: { test: "hi", hello: "howdy" } } },
count = getCount(obj);
console.log(count);

答案 3 :(得分:0)
使用您提到的任何一种方法进行循环。
这样的事情:
var obj = {
"foo": "hello",
"bar": "hi",
"test": {
"foo": "foo",
"bar": {
"test": "hi",
"hello": "howdy"
}
}
}
function count_strings(obj) {
var count = 0;
var keys = Object.keys(obj);
for (var i=0, l=keys.length; i<l; i++) {
if (typeof obj[keys[i]] === 'object') {
count += count_strings(obj[keys[i]]);
} else if (typeof obj[keys[i]] === 'string') {
count++;
}
}
return count;
}
document.querySelector('.output').innerHTML = count_strings(obj);
<div class="output"></div>
答案 4 :(得分:0)
这也是我的50%。
function checkString(str){
var count = 0;
if(typeof str === 'string'){
return 1;
}
Object.keys(str).forEach(function(v){
console.log(str[v]);
if(typeof str[v] === 'object') count = count + checkString(str[v])
else count ++;
})
return count;
}
var obj = {
"foo": "hello",
"bar": "hi",
"test": {
"foo": "foo"
"bar": {
"test": "hi",
"hello": "howdy"
}
}
};
console.log(checkString(obj));