1

I've got a data set simplified to the following

var data = {
  foo: 'bar'
  children: [
    {
      foo: 'bar'
      children: [ 
        { foo: 'bar' }, // count
        { foo: 'bar' }, // count
        {
          foo: 'bar'
          children: [
            { foo: 'bar' }, // count
            { foo: 'bar' }, // count
          ]
        },
        { foo: 'bar' }, // count
      ]
    },
    {
      // etc
    }
  ]
}

There's a lot more of it than that. Any number of objects below nested.

{
  foo: 'bar'
  children: []
}

I want to be able to calculate the total 'last children' of any 'node' in the structure. So far I have written a quick script that will work it out from the top level using a counter variable scoped outside of the recursing function - but that stop it being re-usable.

var total = 0;

var countLastChildren = function(object) {

  if(object.children) {
    object.children.forEach(function(el){
      countLastChildren(el);
    }); 
  } else {
    total++;
  }
}
countLastChildren(data);
console.log(total);

I can't quite get my head round how to scope the counter inside countLastChildren() to allow it to return a value and make it re-usable by passing in different objects or objects nested within my main structure.

Any ideas? Thanks

2
  • If data is the structure shown, what would be the desired result from countLastChildren(data)? 7 (all the children of the top-most level), or 2 (just the lowest level children), or...? Commented Aug 14, 2013 at 11:31
  • I've added some comments to show where I'd like to 'count'. It's basically count all objects without children. Commented Aug 14, 2013 at 11:34

2 Answers 2

4

You can just have the function return the count:

var countLastChildren = function(object) {

    if(object.children) {
        var return_val = 0;
        object.children.forEach(function(el){
            return_val += countLastChildren(el);
        });
        return return_val; 
    } else {
        return 1;
    }
}
console.log(countLastChildren(data));
Sign up to request clarification or add additional context in comments.

2 Comments

Ah that's right, I thought I was missing something simple. It's hard to visualise recursion (particularly including return values) sometimes
Marking this one as accepted since it points out a good change in my original code :) Probly easiest to follow for a googler too
2

Some code golf:

function Total(obj) {
      return obj.children 
      ? obj.children.map(Total).reduce(function (prev, cur) { return prev + cur; }) 
      : 1;
}

1 Comment

really like that. in fact really like any use of map/reduce :-) can confirm that works on my full set of data. Would need underscore or something if used in the browser though

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.