最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Javascript nested objects from string - Stack Overflow

programmeradmin5浏览0评论

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.

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.

Share Improve this question asked Oct 3, 2011 at 21:14 user977433user977433 731 silver badge4 bronze badges 7
  • 2 What's your scenario and final goal? I suspect that there is a better way to achieve your ultimate goal rather than trying to do something like this. – Darin Dimitrov Commented Oct 3, 2011 at 21:16
  • is this an interview question? – Yevgeny Simkin Commented Oct 3, 2011 at 21:16
  • There is something similar in YUI to create objects. I'll see if I can find it. – BNL Commented Oct 3, 2011 at 21:21
  • possible duplicate of Building object hierarchy from a 'namespace' string – Felix Kling Commented Oct 3, 2011 at 21:23
  • Nearly everything is possible with JavaScript; some things are just far less efficient... – beatgammit Commented Oct 3, 2011 at 21:26
 |  Show 2 more comments

5 Answers 5

Reset to default 10
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);

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

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.

Here you go:

var string = "a.b.c",
   array = string.split('.');
JSON.parse("{\"" + array.join('": {\"') + "\": {" +array.map(function () {return '}'}).join('') + "}")

Example

Here's my take on it:

function ensureKeys(str, obj) {
    for(var parts = str.split('.'), i=0, l=parts.length, cache=obj; i<l; i++) {
        if(!cache[parts[i]]) { 
            cache[parts[i]] = {};
        }
        cache = cache[parts[i]];
    }

    return obj;
}

var obj = {};
ensureKeys('a.b.c', obj);
// obj = { a: { b: { c: {} } } }
发布评论

评论列表(0)

  1. 暂无评论