Voici ce que disent les documents officiels
updateIn(keyPath: Array<any>, updater: (value: any) => any): List<T>
updateIn(keyPath: Array<any>, notSetValue: any, updater: (value: any) => any): List<T>
updateIn(keyPath: Iterable<any, any>, updater: (value: any) => any): List<T>
updateIn(keyPath: Iterable<any, any>, notSetValue: any, updater: (value: any) => any): List<T>
Il n'y a aucun moyen pour un développeur Web normal (pas un programmeur fonctionnel) de comprendre cela!
J'ai un cas assez simple (pour une approche non fonctionnelle).
var arr = [];
arr.push({id: 1, name: "first", count: 2});
arr.push({id: 2, name: "second", count: 1});
arr.push({id: 3, name: "third", count: 2});
arr.push({id: 4, name: "fourth", count: 1});
var list = Immutable.List.of(arr);
Comment puis-je mettre à jour list
où l'élément avec le nom tiers a son nombre défini sur 4 ?
javascript
functional-programming
immutable.js
Vitalii Korsakov
la source
la source
Réponses:
Le cas le plus approprié est d'utiliser les deux méthodes
findIndex
etupdate
.PS Il n'est pas toujours possible d'utiliser Maps. Par exemple, si les noms ne sont pas uniques et que je souhaite mettre à jour tous les éléments avec les mêmes noms.
la source
Avec .setIn (), vous pouvez faire la même chose:
Si nous ne connaissons pas l'index de l'entrée, nous voulons mettre à jour. Il est assez facile de le trouver en utilisant .findIndex () :
J'espère que ça aide!
la source
{ }
intérieurfromJS( )
, sans les accolades, ce n'est pas un JS valide.Explication
La mise à jour des collections Immutable.js renvoie toujours les nouvelles versions de ces collections en laissant l'original inchangé. Pour cette raison, nous ne pouvons pas utiliser la
list[2].count = 4
syntaxe de mutation de JavaScript . Au lieu de cela, nous devons appeler des méthodes, comme nous pourrions le faire avec les classes de collection Java.Commençons par un exemple plus simple: juste les décomptes dans une liste.
Maintenant , si nous voulions mettre à jour le 3ème article, un tableau JS plaine pourrait ressembler à :
counts[2] = 4
. Puisque nous ne pouvons pas utiliser de mutation et que nous devons appeler une méthode, nous pouvons utiliser à la place:counts.set(2, 4)
- cela signifie définir la valeur4
à l'index2
.Mises à jour profondes
L'exemple que vous avez donné a cependant des données imbriquées. Nous ne pouvons pas simplement utiliser
set()
sur la collection initiale.Les collections Immutable.js ont une famille de méthodes dont les noms se terminent par "In" qui vous permettent d'apporter des modifications plus profondes dans un ensemble imbriqué. Les méthodes de mise à jour les plus courantes ont une méthode "In" associée. Par exemple car
set
il y en asetIn
. Au lieu d'accepter un index ou une clé comme premier argument, ces méthodes "In" acceptent un "chemin de clé". Le chemin de clé est un tableau d'index ou de clés qui illustre comment accéder à la valeur que vous souhaitez mettre à jour.Dans votre exemple, vous vouliez mettre à jour l'élément dans la liste à l'index 2, puis la valeur à la clé «count» dans cet élément. Le chemin clé serait donc
[2, "count"]
. Le deuxième paramètre de lasetIn
méthode fonctionne exactement commeset
, c'est la nouvelle valeur que nous voulons y mettre, donc:Trouver le bon chemin clé
Pour aller plus loin, vous avez en fait dit que vous vouliez mettre à jour l'élément dont le nom est "trois", ce qui est différent du troisième élément. Par exemple, peut-être que votre liste n'est pas triée, ou peut-être que l'élément nommé «deux» a été supprimé plus tôt? Cela signifie d'abord que nous devons nous assurer que nous connaissons réellement le chemin de clé correct! Pour cela, nous pouvons utiliser la
findIndex()
méthode (qui, d'ailleurs, fonctionne presque exactement comme Array # findIndex ).Une fois que nous avons trouvé l'index dans la liste qui contient l'élément que nous voulons mettre à jour, nous pouvons fournir le chemin d'accès de la clé à la valeur que nous souhaitons mettre à jour:
NB:
Set
vsUpdate
La question d'origine mentionne les méthodes de mise à jour plutôt que les méthodes définies. Je vais expliquer le deuxième argument de cette fonction (appelée
updater
), car il est différent deset()
. Alors que le deuxième argument deset()
est la nouvelle valeur que nous voulons, le deuxième argument deupdate()
est une fonction qui accepte la valeur précédente et renvoie la nouvelle valeur que nous voulons. Ensuite,updateIn()
est la variante "In" deupdate()
qui accepte un chemin clé.Supposons, par exemple, que nous voulions une variante de votre exemple qui ne se contente pas de définir le nombre
4
, mais qui incrémente à la place le nombre existant, nous pourrions fournir une fonction qui en ajoute une à la valeur existante:la source
Vous n'en avez pas besoin
updateIn
, c'est uniquement pour les structures imbriquées. Vous recherchez laupdate
méthode , qui a une signature et une documentation beaucoup plus simples:qui, comme le suggèrent les
Map::update
documents , est " équivalent à:list.set(index, updater(list.get(index, notSetValue)))
".Ce n'est pas ainsi que fonctionnent les listes. Vous devez connaître l'index de l'élément que vous souhaitez mettre à jour, ou vous devez le rechercher.
Cela devrait le faire:
la source
Map
sur aList
est l'approche que vous suggéreriez? Ou dites-vous cela uniquement parce que OP a dit "sélectionner l'élément par nom" et non "sélectionner l'élément par identifiant"?Utilisez .map ()
la source
J'aime vraiment cette approche du site Web de thomastuts :
la source
Vous pouvez utiliser
map
:Mais cela va itérer sur toute la collection.
la source