La fonction map
de underscore.js, si elle est appelée avec un objet javascript, renvoie un tableau de valeurs mappées à partir des valeurs de l'objet.
_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]
y a-t-il un moyen de le faire conserver les clés? c'est-à-dire que je veux une fonction qui retourne
{one: 3, two: 6, three: 9}
Avec Souligner
Le trait de soulignement fournit une fonction _.mapObject
pour mapper les valeurs et conserver les clés.
__.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
_
Avec Lodash
Lodash fournit une fonction _.mapValues
pour mapper les valeurs et conserver les clés.
__.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
_
J'ai réussi à trouver la fonction requise dans lodash, une bibliothèque d’utilitaires semblable au soulignement.
http://lodash.com/docs#mapValues
_.mapValues(object, [callback=identity], [thisArg])
Crée un objet avec les mêmes clés que l'objet et les valeurs générées en exécutant chaque propriété énumérable de l'objet via le rappel. Le rappel est lié à thisArg et appelé avec trois arguments; (valeur, clé, objet).
var mapped = _.reduce({ one: 1, two: 2, three: 3 }, function(obj, val, key) {
obj[key] = val*3;
return obj;
}, {});
console.log(mapped);
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
Je sais que c'est vieux, mais Underscore a maintenant une nouvelle carte pour les objets:
_.mapObject(object, iteratee, [context])
Vous pouvez bien sûr créer une carte flexible pour les tableaux et les objets
_.fmap = function(arrayOrObject, fn, context){
if(this.isArray(arrayOrObject))
return _.map(arrayOrObject, fn, context);
else
return _.mapObject(arrayOrObject, fn, context);
}
Que diriez-vous de cette version en clair JS ( ES6/ES2015 )?
_let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));
_
Si vous voulez mapper sur un objet récursivement (map imbriqué obj), procédez comme suit:
_const mapObjRecursive = (obj) => {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') obj[key] = mapObjRecursive(obj[key]);
else obj[key] = obj[key] * 3;
});
return obj;
};
_
Depuis ES7/ES2016 , vous pouvez utiliser Object.entries
au lieu de _Object.keys
_ comme ceci:
_let newObj = Object.assign(...Object.entries(obj).map([k, v] => ({[k]: v * 3})));
_
_. map renvoie un tableau, pas un objet.
Si vous voulez un objet, vous feriez mieux d'utiliser une fonction différente, comme each
; si vous voulez vraiment utiliser la carte, vous pouvez faire quelque chose comme ceci:
Object.keys(object).map(function(value, index) {
object[value] *= 3;
})
mais c'est déroutant, quand on voit map
on peut s'attendre à avoir un tableau comme résultat et ensuite faire quelque chose avec.
Je sais que cela fait longtemps, mais la solution la plus évidente via fold (ou réduire en js) est toujours manquante. Par souci d'exhaustivité, je vais la laisser ici:
function mapO(f, o) {
return Object.keys(o).reduce((acc, key) => {
acc[key] = f(o[key])
return acc
}, {})
}
Je pense que vous voulez une fonction mapValues (pour mapper une fonction sur les valeurs d'un objet), qui est assez facile à implémenter vous-même:
mapValues = function(obj, f) {
var k, result, v;
result = {};
for (k in obj) {
v = obj[k];
result[k] = f(v);
}
return result;
};
n correctif de mixage pour la carte de soulignement bug : P
_.mixin({
mapobj : function( obj, iteratee, context ) {
if (obj == null) return [];
iteratee = _.iteratee(iteratee, context);
var keys = obj.length !== +obj.length && _.keys(obj),
length = (keys || obj).length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys ? keys[index] : index;
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
if ( _.isObject( obj ) ) {
return _.object( results ) ;
}
return results;
}
});
Une solution de contournement simple qui conserve la bonne clé et retourne sous forme d'objet. Il est toujours utilisé de la même manière que sur un invité, vous pouvez utiliser cette fonction pour remplacer la fonction bugy _.map.
ou simplement comme je l'ai utilisé comme mixin
_.mapobj ( options , function( val, key, list )
Vous pouvez utiliser _.mapValues(users, function(o) { return o.age; });
dans Lodash et _.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
dans le soulignement.
Découvrez la documentation croisée ici: http://jonathanpchen.com/underdash-api/#mapvalues-object-iteratee-identity