从属性数组创建一个动态嵌套对象

25
这听起来像是一个简单的任务,但我还无法完全弄清楚:我有一个数组 :
var array = ['opt1','sub1','subsub1','subsubsub1']

我希望从那个中生成以下对象:

{
  opt1:{
    sub1:{
      subsub1:{
        subsubsub1:{}
      }
    }
  }
}

我有一种方法可以做到这一点,即创建一个字符串并使用eval,但我希望避免这样做,有什么想法吗?

5个回答

42

你可以使用reduce方法:

var array = ['opt1','sub1','subsub1','subsubsub1'];
var object = {};
array.reduce(function(o, s) { return o[s] = {}; }, object);
console.log(object);

但是这个特性仅在ECMAScript 5.1中引入,所以它不会被一些旧版浏览器支持。如果你想要一个能够被旧版浏览器支持的解决方案,你可以使用MDN文章中描述的Polyfill技术或者一个简单的for-loop,像这样:

var array = ['opt1','sub1','subsub1','subsubsub1'];
var object = {}, o = object;
for(var i = 0; i < array.length; i++) {
    o = o[array[i]] = {};
}
console.log(object);


2
或者考虑使用.reduceRight(),以便返回值是顶层对象。 - nnnnnn
对我来说,两者都完全不起作用...尝试使用控制台...?! - Beat
1
@Beat 我已经将代码块转换为片段,这样你就可以看到它们的运行情况。如果你仍然有问题,请尝试组合一个jsfiddle或者提出一个带有演示不起作用的片段的问题--随时可以在你的问题中引用这个答案以获得澄清。 - p.s.w.g
好的。我之前使用了reduce函数返回的对象,而不是object本身。但你的编辑现在让它更清晰了! - Beat

9
你可以使用 reduceRight 来将数组转换为一个对象 '链' :

const array = ['a', 'b', 'c'];
const object = array.reduceRight((obj, next) => ({[next]: obj}), {});

// Example:
console.log(object); // {"a":{"b":{"c":{}}}}


7

您可以使用Lodash set函数。

_.set(yourObject, 'a.b.c')

0

您可以使用以下函数

function arr2nestedObject(myArray){
 var cp_myArray = myArray;
 var lastobj = {};
 while(cp_myArray.length>0){
    newobj = {};
    var prop = cp_myArray.pop();
    newobj[prop] = lastobj;
    lastobj = newobj;
 }
 return lastobj;
}

以下代码:
var myArray = ["personal-information", "address", "street",'Great-Success'];
console.log(JSON.stringify(arr2nestedObject(myArray),undefined,2));

会产生以下输出:

{
  "personal-information": {
   "address": {
    "street": {
     "Great-Success": {}
     }
    }
  }
}

请告诉我这是否是您所想要的。
此致敬礼。

0

正如 @p.s.w.g 的答案所示,这是一个非常好的使用纯JS的答案。但是,如果你想要一种更加描述性和功能性的方式来设置最终嵌套属性的值,你可以使用 ramdajs assocPath https://ramdajs.com/docs/#assocPath,如下所示:

var array = ['opt1','sub1','subsub1','subsubsub1'];

R.assocPath(array, "the value", {}); 

enter image description here

更多细节:

创建一个对象的浅克隆,设置或覆盖必要的节点以创建给定路径,并将特定值放置在该路径的末尾。请注意,这也会将原型属性复制并展平到新对象上。所有非基本属性都是通过引用复制的。

示例:

R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}}

// Any missing or non-object keys in path will be overridden
R.assocPath(['a', 'b', 'c'], 42, {a: 5}); //=> {a: {b: {c: 42}}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接