Reputation: 1778
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
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
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