J'ai un objet:
myObject = { 'a': 1, 'b': 2, 'c': 3 }
Je recherche une méthode native, similaire à Array.prototype.map
, qui serait utilisée comme suit:
newObject = myObject.map(function (value, label) {
return value * value;
});
// newObject is now { 'a': 1, 'b': 4, 'c': 9 }
JavaScript a-t-il une telle fonction map
pour les objets? (Je le veux pour Node.JS, je ne me soucie donc pas des problèmes entre navigateurs.)
Il n'y a pas de map
natif à l'objet Object
, mais qu'en est-il de ceci:
_var myObject = { 'a': 1, 'b': 2, 'c': 3 };
Object.keys(myObject).map(function(key, index) {
myObject[key] *= 2;
});
console.log(myObject);
// => { 'a': 2, 'b': 4, 'c': 6 }
_
Mais vous pouvez facilement parcourir un objet à l'aide de _for ... in
_:
_var myObject = { 'a': 1, 'b': 2, 'c': 3 };
for (var key in myObject) {
if (myObject.hasOwnProperty(key)) {
myObject[key] *= 2;
}
}
console.log(myObject);
// { 'a': 2, 'b': 4, 'c': 6 }
_
Mettre à jour
Beaucoup de gens mentionnent que les méthodes précédentes ne renvoient pas un nouvel objet, mais opèrent plutôt sur l'objet lui-même. D'ailleurs, je voulais ajouter une autre solution qui renvoie un nouvel objet et laisse l'objet d'origine tel quel:
_var myObject = { 'a': 1, 'b': 2, 'c': 3 };
// returns a new object with the values at each key mapped using mapFn(value)
function objectMap(object, mapFn) {
return Object.keys(object).reduce(function(result, key) {
result[key] = mapFn(object[key])
return result
}, {})
}
var newObject = objectMap(myObject, function(value) {
return value * 2
})
console.log(newObject);
// => { 'a': 1, 'b': 4, 'c': 6 }
console.log(myObject);
// => { 'a': 1, 'b': 2, 'c': 3 }
_
Array.prototype.reduce
réduit un tableau à une valeur unique en fusionnant quelque peu la valeur précédente avec la valeur actuelle. La chaîne est initialisée par un objet vide _{}
_. A chaque itération, une nouvelle clé de myObject
est ajoutée avec son carré comme valeur.
Que diriez-vous d’une ligne avec affectation immédiate des variables en JS simple ( ES6/ES2015 )?
Utilisation de opérateur de propagation et nom de clé calculée syntaxe:
let newObj = Object.assign({}, ...Object.keys(obj).map(k => ({[k]: obj[k] * obj[k]})));
Une autre version utilisant réduire:
let newObj = Object.keys(obj).reduce((p, c) => ({...p, [c]: obj[c] * obj[c]}), {});
Premier exemple en tant que fonction:
const oMap = (o, f) => Object.assign({}, ...Object.keys(o).map(k => ({ [k]: f(o[k]) })));
// To square each value you can call it like this:
let mappedObj = oMap(myObj, (x) => x * x);
Si vous souhaitez mapper un objet imbriqué de manière récursive dans un style fonctionnel, procédez comme suit:
const sqrObjRecursive = obj =>
Object.keys(obj).reduce(
(newObj, key) =>
obj[key] && typeof obj[key] === "object"
? { ...newObj, [key]: sqrObjRecursive(obj[key]) } // recurse.
: { ...newObj, [key]: obj[key] * obj[key] }, // square val.
{}
);
Ou plus impérativement, comme ceci:
const sqrObjRecursive = obj => {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === "object") obj[key] = sqrObjRecursive(obj[key]);
else obj[key] = obj[key] * obj[key];
});
return obj;
};
Depuis ES7/ES2016 , vous pouvez utiliser Object.entries()
au lieu de Object.keys()
p. Ex. comme ça:
let newObj = Object.assign(...Object.entries(obj).map(([k, v]) => ({[k]: v * v})));
ES2019 pourrait introduire Object.fromEntries()
, ce qui simplifie encore ceci:
let newObj = Object.fromEntries(Object.entries(([key, val]) => [k, v * v]));
Dans de rares cas, vous aurez peut-être besoin de mapper un objet de type classe qui contient les propriétés d'un objet hérité sur son prototype-chain . Dans ce cas, Object.keys()
ne fonctionnera pas car Object.keys()
n'énumère pas les propriétés inherited. Si vous devez mapper des propriétés héritées, vous devez utiliser for (key in myObj) {...}
.
Voici un exemple d'objet qui hérite des propriétés d'un autre objet et explique comment Object.keys()
ne fonctionne pas dans un tel scénario.
const obj1 = { 'a': 1, 'b': 2, 'c': 3}
const obj2 = Object.create(obj1); // One of multiple ways to inherit an object in JS.
// Here you see how the properties of obj1 sit on the 'prototype' of obj2
console.log(obj2) // Prints: obj2.__proto__ = { 'a': 1, 'b': 2, 'c': 3}
console.log(Object.keys(obj2)); // Prints: an empty Array.
for (key in obj2) {
console.log(key); // Prints: 'a', 'b', 'c'
}
Toutefois, s'il vous plaît, faites-moi une faveur et évitez héritage. :-)
Aucune méthode native, mais lodash # mapValues fera le travail avec brio
_.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
// → { 'a': 3, 'b': 6, 'c': 9 }
C'est assez facile d'en écrire un:
Object.map = function(o, f, ctx) {
ctx = ctx || this;
var result = {};
Object.keys(o).forEach(function(k) {
result[k] = f.call(ctx, o[k], k, o);
});
return result;
}
avec exemple de code:
> o = { a: 1, b: 2, c: 3 };
> r = Object.map(o, function(v, k, o) {
return v * v;
});
> r
{ a : 1, b: 4, c: 9 }
NB: cette version vous permet également de définir (en option) le contexte this
du rappel, tout comme la méthode Array
.
EDIT - a été modifié pour supprimer l'utilisation de Object.prototype
, afin d'éviter tout conflit avec une propriété existante nommée map
sur l'objet.
Vous pouvez utiliser Object.keys
puis forEach
sur le tableau de clés renvoyé:
_var myObject = { 'a': 1, 'b': 2, 'c': 3 },
newObject = {};
Object.keys(myObject).forEach(function (key) {
var value = myObject[key];
newObject[key] = value * value;
});
_
Ou d'une manière plus modulaire:
_function map(obj, callback) {
var result = {};
Object.keys(obj).forEach(function (key) {
result[key] = callback.call(obj, obj[key], key, obj);
});
return result;
}
newObject = map(myObject, function(x) { return x * x; });
_
Notez que _Object.keys
_ renvoie un tableau contenant uniquement les propriétés énumérables de l'objet. Il se comporte donc comme une boucle _for..in
_ avec une vérification hasOwnProperty
.
C'est tout droit, et tout le monde dans la communauté JS le sait. Il y a devrait cette fonctionnalité:
const obj1 = {a:4, b:7};
const obj2 = Object.map(obj1, (k,v) => v + 5);
console.log(obj1); // {a:4, b:7}
console.log(obj2); // {a:9, b:12}
voici l'implémentation naïve:
Object.map = function(obj, fn, ctx){
const ret = {};
for(let k of Object.keys(obj)){
ret[k] = fn.call(ctx || null, k, obj[k]);
});
return ret;
};
c'est super ennuyeux d'avoir à mettre ça en pratique tout le temps;)
Si vous voulez quelque chose d'un peu plus sophistiqué, qui n'interfère pas avec la classe Object, essayez ceci:
let map = function (obj, fn, ctx) {
return Object.keys(obj).reduce((a, b) => {
a[b] = fn.call(ctx || null, b, obj[b]);
return a;
}, {});
};
const x = map({a: 2, b: 4}, (k,v) => {
return v*2;
});
mais il est prudent d’ajouter cette fonction de carte à Object, mais n’ajoutez pas à Object.prototype.
Object.map = ... // fairly safe
Object.prototype.map ... // not ok
Je suis venu ici à la recherche de solutions pour mapper un objet sur un tableau et j'ai obtenu cette page. Au cas où vous viendriez ici chercher la même réponse que moi, voici comment vous pouvez mapper et objecter à un tableau.
Vous pouvez utiliser map pour retourner un nouveau tableau à partir de l'objet, comme ceci:
var newObject = Object.keys(myObject).map(function(key) {
return myObject[key];
});
La réponse acceptée présente deux inconvénients:
Array.prototype.reduce
, car réduire signifie changer la structure d'un type composite, ce qui ne se produit pas dans ce cas.Veuillez noter que toutes les fonctions sont définies sous forme curry.
// small, reusable auxiliary functions
const keys = o => Object.keys(o);
const assign = (...o) => Object.assign({}, ...o);
const map = f => xs => xs.map(x => f(x));
const mul = y => x => x * y;
const sqr = x => mul(x) (x);
// the actual map function
const omap = f => o => {
o = assign(o); // A
map(x => o[x] = f(o[x])) (keys(o)); // B
return o;
};
// mock data
const o = {"a":1, "b":2, "c":3};
// and run
console.log(omap(sqr) (o));
console.log(omap(mul(10)) (o));
o
est réaffecté. Puisque Javascript transmet les valeurs de référence par partage , une copie superficielle de o
est générée. Nous sommes maintenant en mesure de muter o
dans omap
sans muter o
dans la portée parente.map
est ignorée, car map
effectue une mutation de o
. Étant donné que cet effet secondaire reste dans omap
et n'est pas visible dans l'étendue parente, il est totalement acceptable.Ce n'est pas la solution la plus rapide, mais une solution déclarative et réutilisable. Voici la même implémentation qu’une ligne, succincte mais moins lisible:
const omap = f => o => (o = assign(o), map(x => o[x] = f(o[x])) (keys(o)), o);
ES2015 a spécifié les protocoles itérateur et itérable. Mais les objets ne sont toujours pas itérables et donc non mappables. La raison est le mélange des données et du niveau du programme .
JavaScript vient de recevoir la nouvelle méthode Object.fromEntries
.
function mapObject (obj, fn) {
return Object.fromEntries(
Object
.entries(obj)
.map(fn)
)
}
const myObject = { a: 1, b: 2, c: 3 }
const myNewObject = mapObject(myObject, ([key, value]) => ([key, value * value]))
console.log(myNewObject)
Le code ci-dessus convertit l'objet en un tableau imbriqué ([[<key>,<value>], ...]
) sur lequel vous pouvez mapper. Object.fromEntries
reconvertit le tableau en objet.
La bonne chose à propos de ce modèle est que vous pouvez maintenant facilement prendre en compte les clés d’objet lors du mappage.
Object.fromEntries
n'est actuellement supporté que par ces navigateurs/moteurs , néanmoins il existe des polyfill disponibles (par exemple @ babel/polyfill ).
Version minimale (es6):
Object.entries(obj).reduce((a, [k, v]) => (a[k] = v * v, a), {})
Pour une performance maximale.
Si votre objet ne change pas souvent mais nécessite une itération fréquente, je suggère d'utiliser une carte native en tant que cache.
// example object
var obj = {a: 1, b: 2, c: 'something'};
// caching map
var objMap = new Map(Object.entries(obj));
// fast iteration on Map object
objMap.forEach((item, key) => {
// do something with an item
console.log(key, item);
});
Object.entries fonctionne déjà dans Chrome, Edge, Firefox et beta Opera. Il s'agit donc d'une fonctionnalité évolutive. Il provient de l'ES7, alors remplissez-le https://github.com/es-shims/Object.entries pour IE où cela ne fonctionne pas.
vous pouvez utiliser la méthode map
et forEach
sur les tableaux, mais si vous voulez l'utiliser sur Object
, vous pouvez l'utiliser avec twist comme ci-dessous:
tilisation de Javascript (ES6)
var obj = { 'a': 2, 'b': 4, 'c': 6 };
Object.entries(obj).map( v => obj[v[0]] *= v[1] );
console.log(obj); //it will log as {a: 4, b: 16, c: 36}
var obj2 = { 'a': 4, 'b': 8, 'c': 10 };
Object.entries(obj2).forEach( v => obj2[v[0]] *= v[1] );
console.log(obj2); //it will log as {a: 16, b: 64, c: 100}
tilisation de jQuery
var ob = { 'a': 2, 'b': 4, 'c': 6 };
$.map(ob, function (val, key) {
ob[key] *= val;
});
console.log(ob) //it will log as {a: 4, b: 16, c: 36}
Ou vous pouvez utiliser d'autres boucles aussi comme la méthode $.each
comme ci-dessous exemple:
$.each(ob,function (key, value) {
ob[key] *= value;
});
console.log(ob) //it will also log as {a: 4, b: 16, c: 36}
EDIT: La manière canonique d'utiliser les nouvelles fonctionnalités de JavaScript est -
const identity = x =>
x
const omap = (f = identity, o = {}) =>
Object.fromEntries(
Object.entries(o).map(([ k, v ]) =>
[ k, f(v) ]
)
)
Où o
est un objet et f
est votre fonction de mappage. Ou on pourrait dire, étant donné une fonction de a -> b
et un objet avec des valeurs de type a
, produire un objet avec des valeurs de type b
. En tant que pseudo signature de type -
// omap : (a -> b, { a }) -> { b }
La réponse originale a été écrite pour démontrer un puissant combinateur, mapReduce
qui nous permet de penser notre transformation différemment.
m
, la fonction de mappage - vous permet de transformer l'élément entrant avant…r
, la fonction réduisant - cette fonction combine l'accumulateur avec le résultat de l'élément mappéIntuitivement, mapReduce
crée un nouveau réducteur que nous pouvons connecter directement à Array.prototype.reduce
. Mais plus important encore, nous pouvons implémenter notre implémentation de foncteur d’objet omap
clairement en utilisant l’objet monoïde, Object.assign
et {}
.
const identity = x =>
x
const mapReduce = (m, r) =>
(a, x) => r (a, m (x))
const omap = (f = identity, o = {}) =>
Object
.keys (o)
.reduce
( mapReduce
( k => ({ [k]: f (o[k]) })
, Object.assign
)
, {}
)
const square = x =>
x * x
const data =
{ a : 1, b : 2, c : 3 }
console .log (omap (square, data))
// { a : 1, b : 4, c : 9 }
Notez que la seule partie du programme que nous avons dû écrire est l’implémentation de la cartographie elle-même -
k => ({ [k]: f (o[k]) })
Ce qui signifie que, étant donné un objet connu o
et une clé k
, construisez un objet et dont la propriété calculée k
est le résultat de l'appel de f
sur la valeur de la clé, o[k]
.
Nous avons un aperçu du potentiel de séquençage de mapReduce
si nous résumons d'abord oreduce
// oreduce : (string * a -> string * b, b, { a }) -> { b }
const oreduce = (f = identity, r = null, o = {}) =>
Object
.keys (o)
.reduce
( mapReduce
( k => [ k, o[k] ]
, f
)
, r
)
// omap : (a -> b, {a}) -> {b}
const omap = (f = identity, o = {}) =>
oreduce
( mapReduce
( ([ k, v ]) =>
({ [k]: f (v) })
, Object.assign
)
, {}
, o
)
Tout fonctionne de la même façon, mais omap
peut maintenant être défini à un niveau supérieur. Bien sûr, le nouveau Object.entries
donne un air idiot, mais l'exercice reste important pour l'apprenant.
Vous ne verrez pas tout le potentiel de mapReduce
ici, mais je partage cette réponse car il est intéressant de voir à quel point elle peut être appliquée. Si vous êtes intéressé par la façon dont il est dérivé et par d'autres moyens, cela pourrait être utile, veuillez vous reporter à cette réponse .
Le map function
n’existe pas sur le Object.prototype
mais vous pouvez l’émuler de la sorte.
var myMap = function ( obj, callback ) {
var result = {};
for ( var key in obj ) {
if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
if ( typeof callback === 'function' ) {
result[ key ] = callback.call( obj, obj[ key ], key, obj );
}
}
}
return result;
};
var myObject = { 'a': 1, 'b': 2, 'c': 3 };
var newObject = myMap( myObject, function ( value, key ) {
return value * value;
});
Je suis tombé sur cette question en tant que premier élément d'une recherche Google en essayant d'apprendre à le faire, et je pensais partager avec d'autres folsk la solution récemment trouvée, qui utilise le package npm immuable.
Je pense qu'il est intéressant de le partager car immuable utilise la situation EXACT de l'OP dans sa propre documentation. Ce qui suit n'est pas mon code, mais provient de la documentation immuable-js actuelle:
const { Seq } = require('immutable')
const myObject = { a: 1, b: 2, c: 3 }
Seq(myObject).map(x => x * x).toObject();
// { a: 1, b: 4, c: 9 }
Non pas que Seq ait d'autres propriétés ("Seq décrit une opération lazy, leur permettant de chaîner efficacement l'utilisation de toutes les méthodes de collecte d'ordre supérieur (telles que map et filter) en ne créant pas de collections intermédiaires") et que d'autres données immuables-js. les structures peuvent aussi faire le travail assez efficacement.
Toute personne utilisant cette méthode devra bien sûr avoir npm install immutable
et voudra peut-être lire la documentation:
Basé sur la réponse de @Amberlamps, voici une fonction utilitaire (en tant que commentaire, elle avait l'air moche)
function mapObject(obj, mapFunc){
return Object.keys(obj).reduce(function(newObj, value) {
newObj[value] = mapFunc(obj[value]);
return newObj;
}, {});
}
et l'utilisation est:
var obj = {a:1, b:3, c:5}
function double(x){return x * 2}
var newObj = mapObject(obj, double);
//=> {a: 2, b: 6, c: 10}
var myObject = { 'a': 1, 'b': 2, 'c': 3 };
Object.prototype.map = function(fn){
var oReturn = {};
for (sCurObjectPropertyName in this) {
oReturn[sCurObjectPropertyName] = fn(this[sCurObjectPropertyName], sCurObjectPropertyName);
}
return oReturn;
}
Object.defineProperty(Object.prototype,'map',{enumerable:false});
newObject = myObject.map(function (value, label) {
return value * value;
});
// newObject is now { 'a': 1, 'b': 4, 'c': 9 }
Vous pouvez utiliser une simple boucle for-in à travers des paires ordonnées. J'ai utilisé hasOwnProperty()
parce que vous avez créé trois propriétés (avec des valeurs) pour votre objet. La première méthode ne crée pas de carte. Au lieu de cela, il applique simplement la fonction à un seul élément, ce qui peut considérablement accélérer l'exécution dans de nombreuses situations.
La deuxième méthode crée une carte de la même manière que la première, mais est probablement plus lente que d’autres réponses fournies ici.
var myObject = { 'a': 1, 'b': 2, 'c': 3 }
//Doesn't create a map, just applies the function to a specific element
function getValue(key) {
for (var k in myObject) {
if (myObject.hasOwnProperty(key)) {
var value = myObject[key]
return value * value; //stops iteration
}
}
}
//creates a map (answers question, but above function is better in some situations)
var newObject = {};
makeMap();
function makeMap() {
for (var k in myObject) {
var value = myObject[k];
newObject[k] = value * value;
}
}
console.log(newObject); //mapped array
Input: <input id="input" value="" placeholder="a, b or c"><br>
Output:<input id="output"><br>
<button onclick="output.value=getValue(input.value)" >Get value</button>
Commencez par convertir votre collection HTMLCollection à l’aide de Object.entries (collection). Ensuite, c’est une chose que vous pouvez maintenant utiliser la méthode .map.
Object.entries(collection).map(...)
Si vous êtes intéressé par map
configurant non seulement des valeurs mais également des clés, j'ai écrit Object.map(valueMapper, keyMapper)
, qui se comporte de la manière suivante:
var source = { a: 1, b: 2 };
function sum(x) { return x + x }
source.map(sum); // returns { a: 2, b: 4 }
source.map(undefined, sum); // returns { aa: 1, bb: 2 }
source.map(sum, sum); // returns { aa: 2, bb: 4 }
J'avais besoin d'une version permettant de modifier les clés également (basée sur les réponses @Amberlamps et @yonatanmn);
var facts = [ // can be an object or array - see jsfiddle below
{uuid:"asdfasdf",color:"red"},
{uuid:"sdfgsdfg",color:"green"},
{uuid:"dfghdfgh",color:"blue"}
];
var factObject = mapObject({}, facts, function(key, item) {
return [item.uuid, {test:item.color, oldKey:key}];
});
function mapObject(empty, obj, mapFunc){
return Object.keys(obj).reduce(function(newObj, key) {
var kvPair = mapFunc(key, obj[key]);
newObj[kvPair[0]] = kvPair[1];
return newObj;
}, empty);
}
factObject =
{
"asdfasdf": {"color":"red","oldKey":"0"},
"sdfgsdfg": {"color":"green","oldKey":"1"},
"dfghdfgh": {"color":"blue","oldKey":"2"}
}
Edit: léger changement à passer à l'objet de départ {}. Lui permet d'être [] (si les clés sont des entiers)
J'aime les exemples qui utilisent Object.fromEntries
tels que celui-ci , mais ils ne sont quand même pas très faciles à utiliser. Les réponses qui utilisent Object.keys
puis recherchent la key
effectuent en réalité plusieurs recherches qui peuvent ne pas être nécessaires.
Je souhaitais qu'il y ait une fonction Object.map
, mais nous pouvons créer la nôtre et l'appeler objectMap
avec la possibilité de modifier à la fois key
et value
:
Utilisation (JavaScript):
const myObject = { 'a': 1, 'b': 2, 'c': 3 };
// keep the key and modify the value
let obj = objectMap(myObject, val => val * 2);
// obj = { a: 2, b: 4, c: 6 }
// modify both key and value
obj = objectMap(myObject,
val => val * 2 + '',
key => (key + key).toUpperCase());
// obj = { AA: '2', BB: '4', CC: '6' }
Code (TypeScript):
interface Dictionary<T> {
[key: string]: T;
}
function objectMap<TValue, TResult>(
obj: Dictionary<TValue>,
valSelector: (val: TValue, obj: Dictionary<TValue>) => TResult,
keySelector?: (key: string, obj: Dictionary<TValue>) => string,
ctx?: Dictionary<TValue>
) {
const ret = {} as Dictionary<TResult>;
for (const key of Object.keys(obj)) {
const retKey = keySelector
? keySelector.call(ctx || null, key, obj)
: key;
const retVal = valSelector.call(ctx || null, obj[key], obj);
ret[retKey] = retVal;
}
return ret;
}
Si vous n'utilisez pas TypeScript, copiez le code ci-dessus dans TypeScript Playground pour obtenir le code JavaScript.
De plus, la raison pour laquelle je mets keySelector
après valSelector
dans la liste des paramètres est qu’elle est facultative.
* Certains crédits vont à alexander-mills ' answer .
mapEntries prend une fonction de rappel appelée à chaque entrée de l'objet avec les paramètres value, key et object. Il devrait renvoyer une nouvelle valeur.
mapEntries doit retourner un nouvel objet avec les nouvelles valeurs renvoyées par le rappel.
Object.prototype.mapEntries = function(mapEntriesCB) {
return Object.fromEntries(Object.entries(this).map(
([key, value]) => [key, mapEntriesCB(value, key, this)]
));
}
// Usage example:
var object = {a: 1, b: 2, c: 3}
var newObject = object.mapEntries(value => value * value)
console.log(newObject)
//> {a: 1, b: 4, c: 9}
Je voulais spécifiquement utiliser la même fonction que celle que j’utilisais pour les tableaux pour un seul objet et je voulais que cela reste simple. Cela a fonctionné pour moi:
var mapped = [item].map(myMapFunction).pop();
Hey a écrit une petite fonction de mappeur qui pourrait aider.
function propertyMapper(object, src){
for (var property in object) {
for (var sourceProp in src) {
if(property === sourceProp){
if(Object.prototype.toString.call( property ) === '[object Array]'){
propertyMapper(object[property], src[sourceProp]);
}else{
object[property] = src[sourceProp];
}
}
}
}
}
Je ne manipule que des chaînes pour réduire les exemptions:
Object.keys(params).map(k => typeof params[k] == "string" ? params[k] = params[k].trim() : null);
settings = {
message_notification: {
value: true,
is_active: true,
slug: 'message_notification',
title: 'Message Notification'
},
support_notification: {
value: true,
is_active: true,
slug: 'support_notification',
title: 'Support Notification'
},
};
let keys = Object.keys(settings);
keys.map(key=> settings[key].value = false )
console.log(settings)
ES6:
Object.prototype.map = function(mapFunc) {
return Object.keys(this).map((key, index) => mapFunc(key, this[key], index));
}
ES2015:
Object.prototype.map = function (mapFunc) {
var _this = this;
return Object.keys(this).map(function (key, index) {
return mapFunc(key, _this[key], index);
});
};
test en noeud:
> a = {foo: "bar"}
{ foo: 'bar' }
> a.map((k,v,i) => v)
[ 'bar' ]
Ma réponse est en grande partie basée sur la réponse la mieux notée ici et j'espère que tout le monde comprend (ayez la même explication sur mon GitHub aussi). C'est pourquoi son implémentation avec la carte fonctionne:
Object.keys(images).map((key) => images[key] = 'url(' + '"' + images[key] + '"' +
')');
Le but de la fonction est de prendre un objet et de modifier le contenu d'origine de l'objet en utilisant une méthode disponible pour tous les objets (objets et tableaux) sans renvoyer de tableau. Presque tout dans JS est un objet, et pour cette raison, les éléments situés plus en aval de l'héritage peuvent potentiellement utiliser techniquement ceux disponibles pour ceux situés en amont (et inversement, il apparaît).
La raison pour laquelle cela fonctionne est due au fait que les fonctions .map renvoient un tableau Obligeant à fournir un RETOUR explicite ou implicite d'un tableau au lieu de modifier simplement un objet existant. Vous incitez essentiellement le programme à penser que l’objet est un tableau en utilisant Object.keys, ce qui vous permettra d’utiliser la fonction map en agissant sur les valeurs auxquelles les clés individuelles sont associées (j’ai en fait retourné accidentellement des tableaux mais je les ai corrigés). Tant qu'il n'y a pas de retour dans le sens habituel, il n'y aura pas de tableau créé avec l'objet d'origine intact et modifié comme programmé.
Ce programme particulier prend un objet appelé images et prend les valeurs de ses clés et ajoute des balises url à utiliser dans une autre fonction. L'original est ceci:
var images = {
snow: 'https://www.trbimg.com/img-5aa059f5/turbine/bs-md-weather-20180305',
sunny: 'http://www.cubaweather.org/images/weather-photos/large/Sunny-morning-east-
Matanzas-city- Cuba-20170131-1080.jpg',
rain: 'https://i.pinimg.com/originals/23/d8
/ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg' };
... et modifié est ceci:
var images = {
snow: url('https://www.trbimg.com/img-5aa059f5/turbine/bs-md-weather-20180305'),
sunny: url('http://www.cubaweather.org/images/weather-photos/large/Sunny-morning-
east-Matanzas-city- Cuba-20170131-1080.jpg'),
rain: url('https://i.pinimg.com/originals/23/d8
/ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg')
};
La structure d'origine de l'objet reste intacte, permettant un accès normal à la propriété tant qu'il n'y a pas de retour. Ne le faites PAS retourner un tableau comme d'habitude et tout ira bien. L'objectif est de réaffecter les valeurs d'origine (images [clé]) à ce qui est voulu et pas autre chose. Autant que je sache, afin d'empêcher la sortie d'un tableau, il DOIT y avoir RÉAFFECTATION des images [clé] et aucune demande implicite ou explicite de retourner un tableau (l'attribution de variable le fait et faisait des va-et-vient pour moi).
MODIFIER:
Il va aborder son autre méthode concernant la création d’un nouvel objet pour éviter de modifier l’objet original (et une réaffectation semble toujours nécessaire pour éviter de créer accidentellement un tableau en sortie). Ces fonctions utilisent la syntaxe de flèche et sont si vous voulez simplement créer un nouvel objet pour une utilisation future.
const mapper = (obj, mapFn) => Object.keys(obj).reduce((result, key) => {
result[key] = mapFn(obj)[key];
return result;
}, {});
var newImages = mapper(images, (value) => value);
La façon dont ces fonctions fonctionnent est la suivante:
mapFn prend la fonction à ajouter ultérieurement (dans ce cas (valeur) => valeur) et renvoie simplement tout ce qui y est stocké en tant que valeur pour cette clé (ou multiplié par deux si vous modifiez la valeur de retour comme il l'a fait) dans mapFn ( obj) [clé],
puis redéfinit la valeur d'origine associée à la clé dans le résultat [clé] = mapFn (obj) [clé]
et retourne l'opération effectuée sur le résultat (l'accumulateur situé dans les crochets initiés à la fin de la fonction .reduce).
Tout cela est en cours d'exécution sur l'objet choisi et ENCORE, il NE PEUT PAS être une requête implicite pour un tableau retourné et ne fonctionne que lorsque vous réaffectez des valeurs aussi loin que je peux le dire. Ceci nécessite une gymnastique mentale mais réduit les lignes de code nécessaires, comme on peut le voir ci-dessus. La sortie est exactement la même que celle visible ci-dessous:
{snow: "https://www.trbimg.com/img-5aa059f5/turbine/bs-
md-weather-20180305", sunny: "http://www.cubaweather.org/images/weather-
photos/l…morning-east-Matanzas-city-Cuba-20170131-1080.jpg", rain:
"https://i.pinimg.com/originals/23/d8
/ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg"}
Gardez à l'esprit que cela a fonctionné avec NON-NUMBERS. Vous pouvez dupliquer n’importe quel objet simplement en retournant la valeur dans la fonction mapFN.