Benedict Lewis
Benedict Lewis

Reputation: 2813

Generated recursive object based on array

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?

Upvotes: 3

Views: 100

Answers (4)

Nenad Vracar
Nenad Vracar

Reputation: 122047

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)

Upvotes: 6

Thomas
Thomas

Reputation: 12637

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).

Upvotes: 2

Angels
Angels

Reputation: 230

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);

Upvotes: 0

War10ck
War10ck

Reputation: 12508

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);

Upvotes: 0

Related Questions