问题描述
let a=["a","b","c"];
而且我想将该数组转换为(可以更改原始数组,无所谓)我想称之为“递归对象”的内容:
//in json format just to demonstrate
"object": {
"a": {
"b":{
"c":{
}
}
}
}
我已经尝试了以下逻辑,但由于引用问题而无法使其正常工作,并且我无法构建递归。
let tempObj;
let obj2;
array.slice().reverse().forEach(function(item,index){
obj2=tempObj;
tempObj[item]="";
});
let arr=["alpha","beta","gamma"];
let magicObj=someMagicFunction(arr);
//magicObj["alpha"]["beta"]["gamma"] contains the value ""
谢谢
解决方法
通过 reduceRight
从数组的最右侧开始聚合您的对象并提供例如空对象/{}
或空字符串/""
作为此方法的初始值...
console.log(
'object :',["a","b","c"]
.reduceRight((obj,key) =>
({ [key]: obj }),{}
)
);
console.log(
'object :',["alpha","beta","gamma"]
.reduceRight((obj,""
)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
... 并且由于代码代码重用始终应该是目标,因此上面的示例更改为...
function createObjectWithParentKeyAndChildValue(value,key) {
return { [key]: value };
}
console.log(
'object :',['a','b','c']
.reduceRight(createObjectWithParentKeyAndChildValue,{})
);
console.log(
'object :',['alpha','beta','gamma']
.reduceRight(createObjectWithParentKeyAndChildValue,'')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
这是一个简单的解决方案:
const arr = ["a","c"];
const result = arr.reverse().reduce((obj,key) => ({[key]: obj}),{})
console.log(result)
这里稍微解释一下:o
是最后一次迭代的结果,v
是数组中的当前元素。 {[v]: o}
创建一个新对象并将属性 v
设置为 o
并返回。
let magicObj = arr.reverse().reduce((obj,prop) => ({ [prop]: obj }),{})
,
这是我纯粹的递归答案:
let a=["a","c"];
const b = (arr = [],obj = null) => {
if (arr.length > 0) {
const { length,[length - 1]: last,...r } = arr;
const rest = Object.values(r);
const nextObj = obj ? { [last]: obj } : { [last]: {} };
return b(rest,nextObj);
}
return obj;
};
console.log(b(a));
,
reduce
/ reduceRight
的答案很棒。但这也可以通过相当简单的递归版本来完成:
const buildDeep = ([p,...ps],val) =>
p == undefined ? val : {[p]: buildDeep (ps,val)}
console .log (buildDeep (['a','c'],{}))
console .log (buildDeep (['alpha','gamma'],''))
在我看来,这比 reduce
更简单。它感觉与您所看到的各种路径设置功能有关,但并不复杂,因为它不必与现有对象一起使用。