kzaiwo
kzaiwo

Reputation: 1778

Clear a variable counter inside forEach loop?

I'm trying to reset a (file public) counter that is used inside a recursive forEach loop.

Basically the code below checks the length of the innermost key-value pair where: length = (key length) + (some strings inserted) + (key value)

var container = ''
var length = 0

function getUpdatedLengthOfInnerMostObjects (obj) {
  Object.keys(obj).forEach(k => {
    if (typeof obj[k] === 'object') {
      getUpdatedLengthOfInnerMostObjects(obj[k])      
    } else {
      container = k + someFunc(obj[k]) + obj[k]
      length += container.length
    }
  })
  return length
}

const sampleObj = {
    "key1": {
        "key2": {
            "key3": {
                "key4a": {
                    "key5a": "value5a"
                },
                "key4b": {
                    "key5b": "value5b"
                },
                "key4c": {
                    "key5c": "value5c"
                },
                "key4d": {
                    "key5d": "value5d"
                }
            }
        }
    }
}

function someFunc (obj) {
    // Some string manipulation here to return variable length, just returning static for simplicity of this example
  return 'xxx'
} 

console.log('length 1st try = ' + getUpdatedLengthOfInnerMostObjects(sampleObj))
console.log('length 2nd try = ' + getUpdatedLengthOfInnerMostObjects(sampleObj))

So the string to get the length of is:

key5axxxvalue5akey5bxxxvalue5bkey5cxxxvalue5ckey5dxxxvalue5d

It results to lengths of 60 and 120. I need it to output 60 and 60.

"length 1st try = 60"
"length 2nd try = 120"

But not sure how to. When I add this before the return statement in the getUpdatedLengthOfInnerMostObjects(), then it always just returns 0.

  const tempLength = length
  length = 0
  return tempLength

What am I missing here??

Fiddle here: https://jsfiddle.net/keechan/cs3prmLx/

Help!

Upvotes: 1

Views: 171

Answers (2)

StackSlave
StackSlave

Reputation: 10617

I think you really want a dig function:

function dig(obj, func){
  let v;
  if(obj instanceof Array){
    for(let i=0,l=obj.length; i<l; i++){
      v = obj[i]; func(v, i, obj);
      if(typeof v === 'object' && v !== null)dig(v, func);
    }
  }
  else{
    for(let i in obj){
      v = obj[i]; func(v, i, obj);
      if(typeof v === 'object' && v !== null)dig(v, func);
    }
  }
}
const sampleObj = {
    "key1": {
        "key2": {
            "key3": {
                "key4a": {
                    "key5a": "value5a"
                },
                "key4b": {
                    "key5b": "value5b"
                },
                "key4c": {
                    "key5c": "value5c"
                },
                "key4d": {
                    "key5d": "value5d"
                }
            }
        }
    }
}
let results = '';
dig(sampleObj, (v,k)=>{
  if(typeof v === 'string'){
    results += k+'xxx'+v;
  }
});
console.log(results); console.log(results.length);

Note that you may have to add more conditions if other steps give you String results in your actual Object.

Upvotes: 0

Arash Hasanzade
Arash Hasanzade

Reputation: 490

You must move length variable into function scope.

try it :

var container = ''


function getUpdatedLengthOfInnerMostObjects (obj) {
    let length = 0
  let getResult = (obj) => {
    Object.keys(obj).forEach(k => {
      if (typeof obj[k] === 'object') {
        getResult(obj[k])      
      } else {
        container = k + someFunc(obj[k]) + obj[k]
        length += container.length
      }
    })
  }
  getResult(obj);
  return length
}

const sampleObj = {
    "key1": {
        "key2": {
            "key3": {
                "key4a": {
                    "key5a": "value5a"
                },
                "key4b": {
                    "key5b": "value5b"
                },
                "key4c": {
                    "key5c": "value5c"
                },
                "key4d": {
                    "key5d": "value5d"
                }
            }
        }
    }
}

function someFunc (obj) {
    // Some string manipulation here to return variable length, just returning static for simplicity of this example
  return 'xxx'
} 

console.log('length 1st try = ' + getUpdatedLengthOfInnerMostObjects(sampleObj))
console.log('length 2nd try = ' + getUpdatedLengthOfInnerMostObjects(sampleObj))

Upvotes: 1

Related Questions