Underscore.js provides _.each
and _.map
on collections, which is nice, but I need to iterate over all attributes of my object. I need to modify the values and preserve the keys. E.g. I've got something like: {a:1, b:2, c:3}
and I need to perform an operation that changes the value but keeps the keys. Let's say, I'll calculate squares, I should get {a:1, b:4, c:9}
. The question is: how to do that using underscore (not interested in vanilla javascript)? I'd love a method like:
var a = {a:1, b:2, c:3}
_.magic(a, function(item){ return item*item; });
Additionally, it would be great if this was possible to chain it, since I'm doing a map, dump result to perform each and then use a map again (because I need to).
Big thanks to Javier92 who pointed me to the right solution.
Anyway, I don't like to use an underscore method that uses another two underscore methods (it's not readable that much), so I came up with a simple wrapper function that is mixed in into underscore:
use it somewhere in your code:
couldn't think of a one-word function (probably there's something better than
updateAttributes
).I looked a little bit more into some of my snippets to see if there was an option to mutate the original object, but I didn't find anything interesting, so I'd go with this :\
I'm hoping there's a more elegant solution though.
_.mapObject
(added in version 1.8) is exactly what you're looking for.For previous versions, can mutate the original object using the third argument to the
_.each
callback.Using
_.reduce
with an initial memo can create a brand new object as well.I'd prefer the
_.reduce
approach. A simple mixin will make it behave exactly like_.map
.As Justin said _.mapObject might be what you were looking for. But this creates a new object (extending
{}
) which might not be what you want (e.g. if it's not a simple object likenew THREE.Vector3()
), Here it's no good to replace the original object with something different.For that case (modifying values in place in the given object) just use _.each with the third parameter of your iteratee function: