I am trying to write a function that counts the occurrence of a particular key in a nested object. In the first function below, I am initializing a counter as an argument parameter, but it won't keep track of the count after the function returns from a recursive episode. In other words, the function will call itself, go into recursion, correctly add 1 to the counter, but when it comes back, the one is gone.
I am new to javascript!
I ended up solving the problem by using a blank array instead of a count; that is, I first recursively collected all the keys of all the nested objects and then counted them. So my question is, why can I keep track of an array, but not a count?
//Code that does not work (keeping track of a count):
const countKeysInObj = function(obj, key, count = 0) {
for (let prop in obj) {
if (prop === key) {
console.log("counting");
count = 1;
}
if (typeof obj[prop] === 'object') {
console.log("recursing");
countKeysInObj(obj[prop], key, count);
}
}
return count;
}
var testobj = { 'e': { 'x': 'y' }, 't': { 'r': { 'e': 'r' }, 'p': { 'y': 'r' } }, 'y': 'e' };
console.log(countKeysInObj(testobj, "e")) // return 1, should be 2;
CodePudding user response:
Try to use the retuned value and set the count variable from the returned recursed function.
const countKeysInObj = function(obj, key, count = 0) {
for (let prop in obj) {
if (prop === key) {
console.log("counting");
count = 1;
}
if (typeof obj[prop] === 'object') {
console.log("recursing");
count = countKeysInObj(obj[prop], key, count); // set count here.
}
}
return count;
}
CodePudding user response:
The call stack keeps track of return values for you.
Consider that the recursive definition of counting the keys is "the count at the current level plus the count resulting from the recursion".
const countKeysInObj = function(obj, key) {
let count = 0;
if (typeof obj === 'object')
for (let prop in obj) {
// for each key, the count is 1 if that key is the target plus the recursive result
count = (prop === key ? 1 : 0) countKeysInObj(obj[prop], key)
}
return count;
}
var testobj = { 'e': { 'x': 'y' }, 't': { 'r': { 'e': 'r' }, 'p': { 'y': 'r' } }, 'y': 'e' };
console.log(countKeysInObj(testobj, "e")) // 2;