如何从 属性 个名称的数组中逐步构建嵌套对象结构?
How does one incrementally build a nested object structure from an array of property names?
我的任务很简单。我有一个字符串数组:
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 ""
谢谢
这是一个简单的解决方案:
const arr = ["a","b","c"];
const result = arr.reverse().reduce((obj, key) => ({[key]: obj}), {})
console.log(result)
这里稍微解释一下:
o
是最后一次迭代的结果,v
是数组中的当前元素。 {[v]: o}
创建一个新对象并将 属性 v
设置为 o
和 returns 那。
let magicObj = arr.reverse().reduce((obj, prop) => ({ [prop]: obj }), {})
通过 reduceRight
从数组的最右侧开始聚合您的对象并提供例如空对象 / {}
或空字符串 / ""
作为此方法的初始值 ...
console.log(
'object :',
["a","b","c"]
.reduceRight((obj, key) =>
({ [key]: obj }), {}
)
);
console.log(
'object :',
["alpha","beta","gamma"]
.reduceRight((obj, key) =>
({ [key]: 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; }
这是我的纯递归答案:
let a=["a","b","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', 'b', 'c'], {}))
console .log (buildDeep (['alpha', 'beta', 'gamma'], ''))
在我看来,这比 reduce
还要简单。它感觉与您在周围看到的各种路径设置功能相关,但不那么复杂,因为它不必与现有对象一起使用。
我的任务很简单。我有一个字符串数组:
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 ""
谢谢
这是一个简单的解决方案:
const arr = ["a","b","c"];
const result = arr.reverse().reduce((obj, key) => ({[key]: obj}), {})
console.log(result)
这里稍微解释一下:
o
是最后一次迭代的结果,v
是数组中的当前元素。 {[v]: o}
创建一个新对象并将 属性 v
设置为 o
和 returns 那。
let magicObj = arr.reverse().reduce((obj, prop) => ({ [prop]: obj }), {})
通过 reduceRight
从数组的最右侧开始聚合您的对象并提供例如空对象 / {}
或空字符串 / ""
作为此方法的初始值 ...
console.log(
'object :',
["a","b","c"]
.reduceRight((obj, key) =>
({ [key]: obj }), {}
)
);
console.log(
'object :',
["alpha","beta","gamma"]
.reduceRight((obj, key) =>
({ [key]: 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; }
这是我的纯递归答案:
let a=["a","b","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', 'b', 'c'], {}))
console .log (buildDeep (['alpha', 'beta', 'gamma'], ''))
在我看来,这比 reduce
还要简单。它感觉与您在周围看到的各种路径设置功能相关,但不那么复杂,因为它不必与现有对象一起使用。