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\$
  • \$\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\$ – 409_Conflict Feb 15 '18 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 '18 at 10:28
  • \$\begingroup\$ @MathiasEttinger Do you mind if I include that fix in the original question? :) \$\endgroup\$ – Letharion Feb 15 '18 at 10:48
  • \$\begingroup\$ No, but you could also leave it as such, others may propose better approaches. \$\endgroup\$ – 409_Conflict Feb 15 '18 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 '18 at 13:10
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, privacy policy and cookie policy

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