3

I have an array, which is a list of keys: ['one', 'two', 'three'].

I need to generate an object, of the following format:

{
  path: 'one',
  nested: {
    path: 'two',
    nested: {
      path: 'three'
    }
  }
}

So far I've tried a couple of approaches, but they seem quite messy (I have one method which uses while(current = array.pop()) but it requires several conditionals to handle the first and last elements.

Is there a neater recursive strategy?

Benedict Lewis
  • 2,733
  • 7
  • 37
  • 78

4 Answers4

6

You can use reduce() method and as accumulator pass object that you want add properties to.

var arr = ['one', 'two', 'three']
var obj = {}

arr.reduce(function(r, e, i) {
  r.path = e;
  return arr[i+1] ? r.nested = {} : r
}, obj)

console.log(obj)

If you want to use just recursion without loop you can create function like this.

var data = ['one', 'two', 'three']
var obj = {}

function makeObj(arr, n, o) {
  if (n == arr.length - 1) o.path = arr[n]
  else {
    o.path = arr[n];
    o.nested = {}
    makeObj(arr, n += 1, o.nested)
  }
  return o.nested
}

makeObj(data, 0, obj)
console.log(obj)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
2

var arr = ['one', 'two', 'three'];
var tree = arr.reduceRight((nested, path) => {
  return nested? {path, nested}: {path};
}, null);

console.log(tree);

or even better/simpler, just:

var arr = ['one', 'two', 'three'];
var tree = arr.reduceRight((nested, path) => ({path, nested}), null);

console.log(tree);

It simplifies things for the JS engine if all objects have the same hidden class (simplified: same property names).

Thomas
  • 11,958
  • 1
  • 14
  • 23
0
let arr = ['one', 'two', 'three'], obj = {};

obj['path'] = arr[arr.length - 1];
for(let i = arr.length - 2; i >= 0; i--) {
  obj = {
    path: arr[i],
    nested: obj
  };
}
console.log(obj);
Angels
  • 230
  • 1
  • 8
0

You can use a decrementing for loop to solve this problem:

var props = ['one','two','three'],
    obj;
    
for(var a = props.length;a--;) {
    var temp = { path: props[a] };
    if(obj) {
        temp.nested = obj;
    }
    obj = temp;
}

console.log(obj);
War10ck
  • 12,387
  • 7
  • 41
  • 54