list = [a,b,c] array to below object form using javascript
a:{
b : {
c : {
}
}
}
IMHO this question is too abstract to be of any transferrable value - you haven't said why you want to do this, though I suspect your example is simply too generic.
I'm not saying there isn't any value in such a reduction algorithm; it's just meaningless without context – anyone who answers has no guarantee they'll be providing something of practical use.
If all these are requirements, I suggest looking at Lodash set() :
Sets the value at
pathofobject. If a portion ofpathdoesn't exist, it's created. Arrays are created for missing index properties while objects are created for all other missing properties. Use_.setWithto customizepathcreation.
As a programming exercise, my take on it is:
function set(keys, value, obj) {
obj = obj || {}
keys = typeof keys === 'string'
? keys.match(/\w+/g)
: Array.prototype.slice.apply(keys)
keys.reduce(function(obj, key, index) {
obj[key] = index === keys.length - 1
? value
: typeof obj[key] === 'object' && obj !== null
? obj[key]
: {}
return obj[key]
}, obj)
return obj
}
// new object
var obj = set(['a', 'b', 'c'], 1)
// { a: { b: { c: 1 } } }
// existing objects
set(['b', 'c'], 2, obj)
// { a: { b: { c: 1 } }, b: { c: 2 } }
// new props
set(['x', 'y'], 3, obj.b)
// { a: { b: { c: 1 } }, b: { c: 2, x: { y: 3 } } }
// existing props
set(['x', 'z'], 4, obj.b)
// { a: { b: { c: 1 } }, b: { c: 2, x: { y: 3, z: 4 } } }
// keys as string
set('x y z', 5, obj)
// { a: { b: { c: 1 } }, b: { c: 2, x: { y: 3, z: 4 } }, x: { y: { z: 5 } } }
obj
In general programming terms, usability and practicality is more valuable than brevity or speed.
Whilst it's fun to see all the complex answers, mine's a bit more draconian... you probably won't find a faster routine for doing this. It exploits that objects are always passed by reference in JavaScript, even during assignment.
function nest(arr) {
for (var obj = {}, ptr = obj, i = 0, j = arr.length; i < j; i++)
ptr = (ptr[arr[i]] = {});
return obj;
}
No recursive calls, no fancy mapping/each, no nested function calls/multiple functions, no long-winded objectAssign, no foreach or other methods that won't work in legacy browsers. Just a simple FOR loop and assignment. Should work all the way back to IE5.
var list = ['a', 'b', 'c'];
var root = {};
list.forEach((item) => {
var current = {};
current[item] = {};
var keys = Object.keys(current);
var t = findRoot(root);
t[keys[0]] = current[keys[0]];
});
function findRoot(obj) {
var keys = Object.keys(obj);
if (keys.length == 0) return obj;
var lastKey = keys[keys.length - 1];
return obj[lastKey];
}
console.log(root);
On a second thought, makeNestedObjWithArrayItemsAsKeys can further be simplified, and written concisely!
const makeNestedObjWithArrayItemsAsKeys = (arr) => {
const reducer = (acc, item) => ({ [item]: acc });
return arr.reduceRight(reducer, {});
};
cc: dvv.avinash Ivan Rahul Sidhant Siddarthan
The Object.assign in the original function (below) is unnecessary... have noticed it thanks to Jason's answer!
It'd be amiss on my part, to not mention that Jason's solution here (as I see it) is the most elegant one of the lot!
const makeNestedObjWithArrayItemsAsKeys = (arr) => {
return arr.reduceRight(
(accumulator, item) => {
const newAccumulator = {};
newAccumulator[item] = Object.assign(
{},
accumulator
);
return newAccumulator;
},
{}
);
};
Given the following list:
const list = ["a", "b", "c"];
...the return value of makeNestedObjWithArrayItemsAsKeys(list) will be the following object:
{
a: {
b: {
c: {}
}
}
}
Hope that answers your question! :)
let list = ['a', 'b', 'c']
let root = {}
let parent = null;
for(let el of list) {
if(parent === null)
parent = nest(el, root)
else {
parent = nest(el, parent);
}
}
function nest(el, parent) {
let node = {}
parent[el] = node;
return node;
}
console.log(root);
Output
{ a: { b: { c: {} } } }
Veera Venkata Avinash
Be Awesome
var name = ["a","b","c","d"] var index = {} var root = index for(var i=0;i<name.length;i++){ var char = name[i]; root[char] = {} root = root[char] // on next iteration context will be // newly created object } console.log(index);