patternjavascriptMinor
Object map() / transmute() method
Viewed 0 times
objectmaptransmutemethod
Problem
I'm somewhat curious on peoples opinion about such a method. I Actually didn't find anything similar in librarys I use on regular bases so far.
This is my implementation:
I normally put it on the Object object and not the prototype. However, usage is like this
result:
I most often use it to translate CSS properties (to vendor prefixes). But I don't see people use an approach like this often in ECMAscript. Any thoughts?
This is my implementation:
Object.map = function _map( obj, transform ) {
if( typeof obj === 'object' && typeof transform === 'function' ) {
Object.keys( obj ).forEach(function _forEach( key ) {
(function _mapping( oldkey, transmuted ) {
if( transmuted && transmuted.length ) {
obj[ transmuted[ 0 ] || oldkey ] = transmuted[ 1 ];
if( transmuted[ 0 ] && oldkey !== transmuted[ 0 ] ) {
delete obj[ oldkey ];
}
}
}( key, transform.apply( obj, [ key, obj[ key ]] ) ));
});
}
};I normally put it on the Object object and not the prototype. However, usage is like this
var foo = {
someProp: 5,
bar: 10,
moar: 20
};
Object.map( foo, function(key, value) {
return [ key.toUpperCase(), value*2 ];
});result:
Object { SOMEPROP=10, BAR=20, MOAR=40}I most often use it to translate CSS properties (to vendor prefixes). But I don't see people use an approach like this often in ECMAscript. Any thoughts?
Solution
First comment, there is no need for the closure inside _forEach which makes the code unnecessarily difficult to read. More importantly I would argue that the function would be much more useful if did not transform the original object and instead returned a new object.
This is not only less dangerous for widely available object but it also makes the function more flexible by allowing it to be chained or used within an expression:
At the very least I would have your original function return the passed in object to allow for chaining or use within an expression.
Object.map = function (obj, mapping) {
var mapped = {};
if (typeof obj !== 'object') {
return mapped;
}
if (typeof mapping !== 'function') {
// We could just return obj but that wouldn't be
// consistent with the rest of the interface which always returns
// a new object.
mapping = function (key, val) {
return [ key, val ];
};
}
Object.keys( obj ).forEach(function (key) {
var transmuted = mapping.apply(obj, [ key, value ]);
if (transmuted && transmuted.length) {
mapped[ transmuted[0] || key ] = kv[ 1 ];
}
});
return mapped;
};This is not only less dangerous for widely available object but it also makes the function more flexible by allowing it to be chained or used within an expression:
Object.map(oldCss, function (key, value) {
// ...
}).doSomethingElse();At the very least I would have your original function return the passed in object to allow for chaining or use within an expression.
Code Snippets
Object.map = function (obj, mapping) {
var mapped = {};
if (typeof obj !== 'object') {
return mapped;
}
if (typeof mapping !== 'function') {
// We could just return obj but that wouldn't be
// consistent with the rest of the interface which always returns
// a new object.
mapping = function (key, val) {
return [ key, val ];
};
}
Object.keys( obj ).forEach(function (key) {
var transmuted = mapping.apply(obj, [ key, value ]);
if (transmuted && transmuted.length) {
mapped[ transmuted[0] || key ] = kv[ 1 ];
}
});
return mapped;
};Object.map(oldCss, function (key, value) {
// ...
}).doSomethingElse();Context
StackExchange Code Review Q#6189, answer score: 4
Revisions (0)
No revisions yet.