Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript nested objects from string

I've got an empty object and a string:

var obj = {};
var str = "a.b.c";

Is there a way I can turn this into

obj = { a: { b: { c: { } } } }

I can't quite wrap my head around this one and I'm not even sure if it would be possible.

like image 570
user977433 Avatar asked Oct 03 '11 21:10

user977433


3 Answers

var obj = {};
var str = "a.b.c";
var arr = str.split('.');
var tmp = obj;

for (var i=0,n=arr.length; i<n; i++){
   tmp[arr[i]]={};
   tmp = tmp[arr[i]];
}

ES6:

let str = "a.b.c",
    arr = str.split('.'),
    obj, o = obj = {};

arr.forEach(key=>{o=o[key]={}});

console.log(obj);

ES6/Reduced (array storage unnecessary):

let str = "a.b.c", obj, o = obj = {};

str.split('.').forEach(key=>o=o[key]={});

console.log(obj);

ES6/Array.prototype.reduce:

let str = "a.b.c", last;

let obj = str.split('.').reduce((o, val) => {
  if (typeof last == 'object')
    last = last[val] = {};
  else
    last = o[val] = {};

  return o;
}, {});

console.log(obj);
like image 145
vol7ron Avatar answered Nov 07 '22 16:11

vol7ron


This is from the yui2 yahoo.js file.

YAHOO.namespace = function() {
  var a=arguments, o=null, i, j, d;
  for (i=0; i<a.length; i=i+1) {
      d=(""+a[i]).split(".");
      o=YAHOO;

      // YAHOO is implied, so it is ignored if it is included
      for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
          o[d[j]]=o[d[j]] || {};
          o=o[d[j]];
      }
  }

  return o;
};

See the source for documentation.

https://github.com/yui/yui2/blob/master/src/yahoo/js/YAHOO.js

like image 3
BNL Avatar answered Nov 07 '22 15:11

BNL


This recursive function returns you the string representation of the desired object

//Usage: getObjectAsString('a.b.c'.split(/\./))
function getObjectAsString (array){
   return !array.length ? '{}' 
             : '{"' + array[0] + '":' + getObjectAsString (array.slice(1)) + '}';
}

Now you can convert the output of getObjectAsString into object using

JSON.parse(getObjectAsString('a.b.c'.split(/\./)))

EDIT: Removed 'Input as String' version as it works only for single letter subparts in the namespace such as the one given in the question (a.b.c) which is generally not the case.

like image 3
Narendra Yadala Avatar answered Nov 07 '22 15:11

Narendra Yadala