naansequitur
naansequitur

Reputation: 33

Recursively create nested object with dynamic keys

I'm comfortable with recursion, but came across a case where I need to create nested objects with variable keys. Have seen other suggestions to use a namespace convention like 'b.c' to figure out where to assign values deeply (see desired output below), but having difficulty with implementation. The structure can be infinitely nested.

// Source
const input = {
  a: {
    type: 'string',
    ex: '1'
  },
  b: {
    type: 'object',
    another: {
      c: {
        type: 'string',
        ex: '2'
      }
    }
  }
}

// Desired
const output = {
  a: '1',
  b: {
    c: '2'
  }
}

// The attempt
function traverse(data, master = {}) {
  Object.entries(data).reduce((collection, [key, value]) => {
    switch (value.type) {
      case 'string':
        collection[key] = value.ex;
        break;
      default:
        collection[key] = traverse(value.another, collection);
    }
    return collection;
  }, master);
}

Running this returns undefined.

Upvotes: 1

Views: 556

Answers (1)

mickl
mickl

Reputation: 49945

Nested traverse should get a brand new object as second parameter, you also need to return a retult from your function, try:

// Source
const input = {
  a: {
    type: 'string',
    ex: '1'
  },
  b: {
    type: 'object',
    another: {
      c: {
        type: 'string',
        ex: '2'
      }
    }
  }
}


// The attempt
function traverse(data, master = {}) {
  return Object.entries(data).reduce((collection, [key, value]) => {
    switch (value.type) {
      case 'string':
        collection[key] = value.ex;
        break;
      default:
        collection[key] = traverse(value.another, {});
    }
    return collection;
  }, master);
}

console.log(traverse(input));

Upvotes: 1

Related Questions