Derek Hoang
Derek Hoang

Reputation: 71

How can I count the number of target key(property) it occurs in an object recursively?

Write a function that counts the number of times a key occurs in an object.

// var testobj = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'};

// countKeysInObj(testobj, 'r') // 1

// countKeysInObj(testobj, 'e') // 2

Here is my code, but it's not working:

var countKeysInObj = function(obj, key) {
  var num = 0;
  for (var prop in obj) {
    if (prop === key) {
      num++;
    }
    var value = obj[prop];
    if (typeof value === 'object') {
      return countKeysInObj(value, key);
    }
  }
  return num;
};

Upvotes: 1

Views: 1270

Answers (3)

KooiInc
KooiInc

Reputation: 122936

To add to previous answers: you can use Object.keys and Array.filter to count the keys. ES2015 example:

'use strict';
let result = document.querySelector('#result');
let testobj = { 'e': { 'x': 'y' }, 
                't': { 'r': { 'e': 'r' }, 
                'p': { 'y':'r',  'r': {'r': '5'} } }, 
                'y': 'e' };
let resultStr = 'Full depth frequency in testObj for key';

result.textContent = `${resultStr} 'r': ${countAllKeysInObject(testobj, 'r')}
${resultStr} 'e': ${countAllKeysInObject(testobj, 'e')}`;

function countAllKeysInObject(obj, findKey) {
  let keyFreq = currentObj => Object.keys(currentObj)
                              .filter( key => key === findKey ).length;
  let nKeys = keyFreq(obj);
  let count = obj => {
    for (let l in obj) {
      nKeys += keyFreq(obj[l]);
      obj[l] instanceof Object && count(obj[l]);
    }
    return nKeys;
  };
  return count(obj);
}
<pre id="result"></pre>

Upvotes: 0

einsteine89
einsteine89

Reputation: 33

The problem is that you return instead of num+=

var countKeysInObj = function(obj, key) {
  var num = 0;
  for (var prop in obj) {
    if (prop === key) {
      num++;
    }
    var value = obj[prop];
    if (typeof value === 'object') {
      num += countKeysInObj(value, key);
    }
  }
  return num;
};

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386680

You need to add the result of the recursive call. And return only at the end of the function, because any nested object would break the loop.

var testobj = { 'e': { 'x': 'y' }, 't': { 'r': { 'e': 'r' }, 'p': { 'y': 'r' } }, 'y': 'e' },
countKeysInObj = function(obj, key) {
    var num = 0;
    for (var prop in obj) {
        if (prop === key) {
            num++;
        }
        var value = obj[prop];
        if (typeof value === 'object') {
            num += countKeysInObj(value, key); // add to num!
        }
    }
    return num;
};

document.write(countKeysInObj(testobj, 'r') + '<br>');
document.write(countKeysInObj(testobj, 'e') + '<br>');

Upvotes: 1

Related Questions