Underscore.js has a very useful map function.
_.map([1, 2, 3], function(num){ return num * 3; });
=> [3, 6, 9]
_.map({one: 1, two: 2, three: 3
If I understand correctly, here's an example, using recursion:
var deepMap = function(f, obj) {
return Object.keys(obj).reduce(function(acc, k) {
if ({}.toString.call(obj[k]) == '[object Object]') {
acc[k] = deepMap(f, obj[k])
} else {
acc[k] = f(obj[k], k)
}
return acc
},{})
}
Then you can use it like so:
var add1 = function(x){return x + 1}
var o = {
a: 1,
b: {
c: 2,
d: {
e: 3
}
}
}
deepMap(add1, o)
//^ { a: 2, b: { c: 3, d: { e: 4 } } }
Note that the mapping function has to be aware of the types, otherwise you'll get unexpected results. So you'd have to check the type in the mapping function if nested properties can have mixed types.
For arrays you could do:
var map1 = function(xs){return xs.map(add1)}
var o = {
a: [1,2],
b: {
c: [3,4],
d: {
e: [5,6]
}
}
}
deepMap(map1, o)
//^ { a: [2,3], b: { c: [4,5], d: { e: [6,7] } } }
Note that the callback is function(value, key) so it works better with composition.