1

I am trying to convert the following array into an object:

var arr = [
  'car.name',
  'car.age',
  'car.event.id',
  'zz.yy.dd.aa',
  'aa.yy.zz.dd.kk'
];

So it will look like this:

var targetObject = {
  car: {
    name: '',
    age: '',
    
    event: {
      id: ''
    }

  }

  ,

  zz: {
    yy: {
      dd: {
        aa: ''
      }
    }
  },
  aa: {
    yy: {
      zz: {
        dd: {
          kk: '',
        }
      }
    }
  }
}

This is my code:

targetObject = {}

function arrayToObject(arr){
  
  //iterate through array and split into items
  for (var i = 0; i < arr.length; ++i){
    var item = arr[i].split(".");


      //iterate through item that has just been splitted
      for (var u = 0; u < item.length; ++u){


        //if item is not in targetobject create new object
        if(!(item[0] in targetObject)){
          targetObject[item[0]] = {}
        } else {
          //else go into the object and add the item/property to the existing object
          targetObject[item[0]][item[u]] = {}
          }
          
      }
  }

console.log(targetObject);
}

arrayToObject(arr);

It outputs only in second level and i can't figure out to do it with the several levels. I know the code is oldschool, so I would also really like to know how this can be done easier.

Batterman
  • 33
  • 2
  • Check here: https://stackoverflow.com/questions/26908996/create-objects-dynamically-out-of-a-dot-notation-like-string/26909342 – ChrisG Sep 14 '21 at 19:19

1 Answers1

1

You could use forEach to loop over array and then split with reduce to build nested object.

var arr = [
  'car.name',
  'car.age',
  'car.event.id',
  'zz.yy.dd.aa',
  'aa.yy.zz.dd.kk'
];

const result = {}

arr.forEach(str => {
  str.split('.').reduce((r, e, i, a) => {
    return r[e] = (r[e] || (a[i + 1] ? {} : ''))
  }, result)
})

console.log(result)

Or with your approach with for loops you just need to keep some reference and update the current nested object, so you could do it like this.

var arr = [
  'car.name',
  'car.age',
  'car.event.id',
  'zz.yy.dd.aa',
  'aa.yy.zz.dd.kk'
];

const targetObject = {}
let ref = targetObject;

function arrayToObject(arr) {
  //iterate through array and split into items
  for (var i = 0; i < arr.length; ++i) {
    var item = arr[i].split(".");

    //iterate through item that has just been splitted
    for (var u = 0; u < item.length; ++u) {
      const last = u == item.length - 1
      const str = item[u]

      if (!ref[str]) {
        ref[str] = (last ? '' : {})
      }

      ref = ref[str]

      if (last) {
        ref = targetObject;
      }

    }
  }
}

arrayToObject(arr);
console.log(targetObject)
Nenad Vracar
  • 111,264
  • 15
  • 131
  • 153