通过字符串键/路径生成嵌套对象结构

时间:2015-09-25 22:13:39

标签: javascript associative-array

我想创建一个名为createAssociativeArray的函数,它会返回两个参数:stringobject,如下所示:

function createAssociativeArray(string, object) {
  //...
}

string的最后一项应获取object数据。请参阅使用/返回示例:

createAssociativeArray('key1.key2.key3', {
  data1: 1,
  data2: 2,
  data3: 3
});

// key1: {
//   key2: {
//     key3: {
//       data1: 1,
//       data2: 2,
//       data3: 3
//     }
//   }
// }

最简单,最健壮的方法是什么?

使用 eval 是不可能的。

我尝试了什么:

function createAssociativeArray(string, object) {
  string = string.split('.');
  return string.reduce(function(_object, _target, i) {
    _object[_target] = (i + 1 === string.length ? object : {});
    return _object;
  }, {});
}

它没有产生预期的结果,因为该对象被重置为{}

[JSFiddle]

10 个答案:

答案 0 :(得分:5)

这是我想出的:

747.00

答案 1 :(得分:3)

我很想知道我是否可以制作一个递归解决方案,所以这就是:

function createAssociativeArray(string, object) {
    if (string === "") return object;
    var stringarr = string.split('.');
    var laststr = stringarr.pop();
    var newobj = {};
    newobj[laststr] = object;
    return createAssociativeArray(stringarr.join("."), newobj);
}

使用JSFiddle演示:https://jsfiddle.net/pt352dxg/

答案 2 :(得分:2)

可能的实施:

Working demo

function createChain(keys, value) {
  var obj = {};
  var target = obj;
  keys = keys.split('.');
  keys.forEach(function(key, index) {
    target = target[key] = index === keys.length - 1 ? value : {};
  });
  target = value;
  return obj;
}

答案 3 :(得分:2)

此函数实际上可以接受可选的现有Object({k:2,kk:3,key1:4})并将其与给定的json路径合并。例如试试chrome调试器控制台:

JSON.stringify(createAssociativeArray('key1.key2.key3', {  data1: 1,  data2: 2,  data3: 3}, {k:2,kk:3, key1:{}}))

将打印出来:

"{"k":2,"kk":3,"key1":{"key2":{"key3":{"data1":1,"data2":2,"data3":3}}}}"

...

  function createAssociativeArray(key, value, data) {
         if(!finalData && data)
           finalData = data;
         var finalData;
         if (!data)
             data = finalData = {};
         var keys = key.split('.');
         if (keys.length < 2) {
           data[keys[0]] = value; 
         } else {
           if (!data[keys[0]])
               data[keys[0]] = {};
           data = data[keys.shift()];              
           createAssociativeArray(keys.join("."),value,data);
         }
         return finalData;
    };

答案 4 :(得分:2)

你原来的尝试非常接近。

function createAssociativeArray(string, object) {
    return string.split('.').reverse().reduce(function (inner, key) {
        var outer = {};
        outer[key] = inner;
        return outer;
    }, object);
}

http://jsfiddle.net/xewoa06t/

答案 5 :(得分:1)

这对我有用:

function createAssociativeArray(string, object){
    var array = string.split('.');
    var aArray = {};
    if(array.length > 1){
         aArray[array[array.length - 1]] = object;
         array.splice(array.length - 1, 1);
         createAssociativeArray(array.join('.'), aArray)
    }else{
        aArray[array[array.length - 1]] = object;
        return aArray
    } 
};


createAssociativeArray('key1.key2.key3', {data1: 1, data2: 2, data3: 3});

基本上,从原始对象开始构建对象,然后包裹&#39;层。在递归周围

答案 6 :(得分:1)

递归函数的好例子!

function createAssociativeArray(string, object) {
  if (string.split('.').length == 1) {
    var outObj = {};
    outObj[string] = object;
    return outObj;
  } else {
    var outObj = {};
    outObj[string.split('.')[0]] = createAssociativeArray(string.split('.').slice(1).join('.'), object);
    return outObj;
  }
}

答案 7 :(得分:0)

使用简单循环更容易,关键点是反向(如@JustcallmeDrago)

function createAssociativeArray(keys, data)
{
  var temp, keyPart
  
  for(keys = keys.split('.'); keys.length; data = temp)
  {
    keyPart = keys.pop()
    temp = {}
    temp[keyPart] = data
  }
  return data
}  

// TEST

x = createAssociativeArray("key1.key2.key3", { data1: "value1", data2: "value2" })

document.write('<pre>'+x+'\n'+x.key1 +'\n'
               +x.key1.key2 + '\n'
               +x.key1.key2.key3 +'\n'
               +x.key1.key2.key3.data1 +'\n'
               +x.key1.key2.key3.data2 +'</pre>')

答案 8 :(得分:0)

由于没有人提出while - 循环解决方案:

function namespace(path, context) {
    var obj = context;
    var s = path.split('.');
    var p;
    while (s.length) {
        p = s.shift();
        obj = obj[p] || (obj[p] = {});
    }
    return context;
}

答案 9 :(得分:0)

ES6一线班轮

(str, obj) => str.split('.').reverse().reduce((inner, key) => ({[key]: inner}), obj);