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.