7
\$\begingroup\$

I've got this recursive generator function. It will traverse an object looking for "leafs", any keys that don't point to sub-objects.

Then it applies one of two actions on the leaf and yields it. Any suggestions for improvement would be appreciated. :)

const obj = {
  a: 'a',
  b: 'b',
  c: {
    d: 'd',
    e: 'e',
  }
};

const clone = toClone => JSON.parse(JSON.stringify(toClone))

function* leafIterator(object, action) {
  for (const key of Object.keys(object)) {
    if (typeof object[key] === 'object') {
      for (const inner of leafIterator(object[key], action)) {
        let oclone = clone(object);
        oclone[key] = inner;
        yield oclone;
      }
    }
    else {
      let oclone = clone(object);
      action(oclone, key);
      yield oclone;
    }
  }
}

for (let o of leafIterator(obj, (s, key) => delete s[key])) {
  console.log('result', o);
}

\$\endgroup\$
5
  • \$\begingroup\$ Not a review so just a comment, but you can always pass functions as parameters: for (let o of leafIterator(obj, (oclone, key) => {delete oclone[key];})) and use them instead of your if: action(oclone, key). \$\endgroup\$ Feb 15, 2018 at 10:01
  • \$\begingroup\$ @MathiasEttinger I could have absolutely sworn that I did just that, but the whole thing blew up. I assumed it had something to do with the recursive nature of the function, and then ended up going with my hardcoded options. But of course, now that try it, it works fine! \$\endgroup\$
    – Letharion
    Feb 15, 2018 at 10:28
  • \$\begingroup\$ @MathiasEttinger Do you mind if I include that fix in the original question? :) \$\endgroup\$
    – Letharion
    Feb 15, 2018 at 10:48
  • \$\begingroup\$ No, but you could also leave it as such, others may propose better approaches. \$\endgroup\$ Feb 15, 2018 at 11:07
  • \$\begingroup\$ I've added this to the question since it better reflects what I meant to write. Hopefully others will still have suggestions, on this or other things. \$\endgroup\$
    – Letharion
    Feb 15, 2018 at 13:10

1 Answer 1

1
\$\begingroup\$

Good things:

  • all lines terminated with a semi-comon
  • strict equality used when checking for objects

I would suggest using const by default since none of the variables/functions get reassigned. If you determine reassignment is necessary then use let. This will help avoid accidental re-assignment.

And is the variable naming oclone Hungarian notation? If so, why not use it for all variables instead of cloned variables?

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.