Je me demande s'il existe une méthode plus simple dans lodash pour remplacer un élément dans une collection JavaScript? (Possible duplicata mais je n'ai pas compris la réponse :)
J'ai regardé leur documentation mais je n'ai rien trouvé
Mon code est:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Can following code be reduced to something like _.XX(arr, {id:1}, {id:1, name: "New Name"});
_.each(arr, function(a, idx){
if(a.id === 1){
arr[idx] = {id:1, name: "Person New Name"};
return false;
}
});
_.each(arr, function(a){
document.write(a.name);
});
Mise à jour: l'objet que j'essaie de remplacer a de nombreuses propriétés comme
{id: 1, Prop1: ..., Prop2: ..., et ainsi de suite}
Solution:
Merci à dfsq, mais j'ai trouvé une solution appropriée dans lodash qui semble fonctionner correctement et qui est assez soignée et je la mets également dans un mixin puisque j'ai cette exigence à de nombreux endroits. JSBin
var update = function(arr, key, newval) {
var match = _.find(arr, key);
if(match)
_.merge(match, newval);
else
arr.push(newval);
};
_.mixin({ '$update': update });
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
_.$update(arr, {id:1}, {id:1, name: "New Val"});
document.write(JSON.stringify(arr));
Solution plus rapide Comme l'a souligné @dfsq, suivre est beaucoup plus rapide
var upsert = function (arr, key, newval) {
var match = _.find(arr, key);
if(match){
var index = _.indexOf(arr, _.find(arr, key));
arr.splice(index, 1, newval);
} else {
arr.push(newval);
}
};
javascript
lodash
Vishal Seth
la source
la source
_.findIndex
pour le match._.findIndex
au lieu de_.find
vous permettra de supprimer à la fois le second_.find
et le_.indexOf
. Vous parcourez le tableau 3 fois alors que tout ce dont vous avez besoin est de 1.Réponses:
Dans votre cas, tout ce que vous avez à faire est de trouver un objet dans un tableau et d'utiliser la
Array.prototype.splice()
méthode, lisez plus de détails ici :la source
indexOf
va être très rapide (elle utilisera les navigateurs natifs Array.prototype.indexOf). Mais quoi qu'il en soit, heureux que vous trouviez une solution qui fonctionne pour vous._.findIndex
? Ensuite, vous n'avez pas besoin d'utiliser_.indexOf
.On dirait que la solution la plus simple consisterait à utiliser ES6
.map
ou lodash_.map
:Cela a pour effet d'éviter de muter le tableau d'origine.
la source
[ES6] Ce code fonctionne pour moi.
la source
updatedItem
tableau if n'inclut pas un élément avec le mêmeid
.Testons maintenant les performances de toutes les méthodes:
Afficher l'extrait de code
la source
Vous pouvez également utiliser findIndex et pick pour obtenir le même résultat:
la source
Au fil du temps, vous devez adopter une approche plus fonctionnelle dans laquelle vous devez éviter les mutations de données et écrire de petites fonctions de responsabilité unique. Avec la norme ECMAScript 6, vous pouvez profiter de paradigme de programmation fonctionnelle en JavaScript avec les fournis
map
,filter
et lesreduce
méthodes. Vous n'avez pas besoin d'un autre lodash, d'un trait de soulignement ou de quoi d'autre pour faire les choses les plus élémentaires.Ci-dessous, j'ai inclus quelques solutions proposées à ce problème afin de montrer comment ce problème peut être résolu en utilisant différentes fonctionnalités de langage:
Utilisation de la carte ES6:
Version récursive - équivalent du mappage:
Nécessite une déstructuration et une répartition du tableau .
Lorsque l'ordre final du tableau n'est pas important, vous pouvez utiliser un
object
comme structure de données HashMap . Très pratique si vous avez déjà une collection de clés en tant queobject
- sinon vous devez d'abord changer votre représentation.Nécessite une répartition du reste des objets , des noms de propriétés calculés et des entrées Object.entries .
la source
Si vous essayez juste de remplacer une propriété, lodash
_.find
et_.set
devrait suffire:la source
Si le point d'insertion du nouvel objet n'a pas besoin de correspondre à l'index de l'objet précédent, le moyen le plus simple de le faire avec lodash consiste à utiliser
_.reject
puis à pousser de nouvelles valeurs dans le tableau:Si vous souhaitez remplacer plusieurs valeurs en un seul passage, vous pouvez effectuer les opérations suivantes (écrites au format non ES6):
la source
En utilisant la fonction lodash unionWith, vous pouvez effectuer un simple upsert vers un objet. La documentation indique qu'en cas de correspondance, elle utilisera le premier tableau. Enveloppez votre objet mis à jour dans [] (tableau) et placez-le comme premier tableau de la fonction union. Spécifiez simplement votre logique de correspondance et si elle est trouvée, elle la remplacera et sinon elle l'ajoutera
Exemple:
la source
Pas mal de variante aussi)
la source
la source
Si vous cherchez un moyen de changer immuablement la collection (comme je l'étais lorsque j'ai trouvé votre question), vous pouvez jeter un œil à immutability-helper , une bibliothèque dérivée de l'utilitaire React original. Dans votre cas, vous accomplirez ce que vous avez mentionné via ce qui suit:
la source
Vous pouvez le faire sans utiliser de lodash.
la source
Immuable , convient pour
ReactJS
:Présumer:
L'élément mis à jour est le deuxième et le nom est changé en
Special Person
:Astuce : le lodash a des outils utiles mais maintenant nous en avons certains sur Ecmascript6 +, donc j'utilise juste une
map
fonction qui existe à la fois surlodash
etecmascript6+
:la source
Je suis tombé sur cela aussi et je l'ai fait simplement de cette façon.
Si on veut on peut le généraliser
la source