My task is straight forward. I have an array of strings:
let a=["a","b","c"];
And i want to convert that array to (can alter the original array, doesn't matter) what i would like to call as "recursive object" just so:
//in json format just to demonstrate
"object": {
"a": {
"b":{
"c":{
}
}
}
}
I've tried the following logic but couldn't get it to work due to reference problem and i couldn't build recursion.
let tempObj;
let obj2;
array.slice().reverse().forEach(function(item,index){
obj2=tempObj;
tempObj[item]="";
});
Just to make sure we are on the same page, another example:
let arr=["alpha","beta","gamma"];
let magicObj=someMagicFunction(arr);
//magicObj["alpha"]["beta"]["gamma"] contains the value ""
Thanks
Start aggregating your object from the array's right most side via reduceRight
and provide eg an empty object / {}
or an empty string / ""
as this method's initial value(s)...
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; }
... and since code code-reuse always should be a goal the above examples change to...
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; }
Here is a simple solution:
const arr = ["a","b","c"]; const result = arr.reverse().reduce((obj, key) => ({[key]: obj}), {}) console.log(result)
Here a little explaination:
o
is the result of the last iteration and v
is the current element in the array. {[v]: o}
creates a new object and sets the property v
to o
and returns that.
let magicObj = arr.reverse().reduce((obj, prop) => ({ [prop]: obj }), {})
there is my pure recursive answer:
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));
The reduce
/ reduceRight
answers are great. But this can also be done with a fairly trivial recursive version:
const buildDeep = ([p, ...ps], val) => p == undefined? val: {[p]: buildDeep (ps, val)} console.log (buildDeep (['a', 'b', 'c'], {})) console.log (buildDeep (['alpha', 'beta', 'gamma'], ''))
To my mind, this is even simpler than reduce
. It feels related to the various path-setting functions you see around, but is less complex since it doesn't have to work with an existing object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.