1. Premiers pas
2. Combinez les fonctions
3. Utilisation partielle (curry)
4. Programmation déclarative
5. Notation quintessentielle
6. Immuabilité et objets
7. Immuabilité et réseaux
8. Objectifs
9. Conclusion
Cet article est la septième partie d'une série d'articles de programmation fonctionnelle intitulée Ramda Style Thinking.
Dans la sixième partie, nous avons parlé de travailler avec des objets JavaScript dans un style fonctionnel et immuable.
Dans cet article, nous parlerons de travaux similaires avec des tableaux.
Lecture des éléments du tableau
Dans la sixième partie, nous avons découvert les différentes fonctions Ramda pour lire les propriétés des objets, telles que prop
, pick
et has
. Ramda a encore plus de méthodes pour lire les éléments d'un tableau.
L'équivalent de prop
pour un tableau est nième ; l'équivalent de pick
est slice et l'équivalent de has
est contains . Jetons-y un œil.
const numbers = [10, 20, 30, 40, 50, 60] nth(3, numbers) // => 40 ( ) nth(-2, numbers) // => 50 ( ) slice(2, 5, numbers) // => [30, 40, 50] (. ) contains(20, numbers) // => true
Slice prend deux index et retourne un sous-tableau qui commence au premier index (à partir de zéro) et inclut tous les éléments jusqu'au deuxième index, mais n'inclut pas l'élément de cet index.
L'accès aux premier et dernier éléments d'un tableau est assez courant, donc Ramda fournit des fonctions courtes pour ces cas, head et last . Il fournit également des fonctions pour obtenir tous les éléments sauf le premier ( queue ), tous sauf le dernier ( init ), les premiers N éléments ( take (N) ) et les derniers N éléments ( takeLast (N) ). Jetons un coup d'œil à eux en action.
const numbers = [10, 20, 30, 40, 50, 60] head(numbers) // => 10 tail(numbers) // => [20, 30, 40, 50, 60] last(numbers) // => 60 init(numbers) // => [10, 20, 30, 40, 50] take(3, numbers) // => [10, 20, 30] takeLast(3, numbers) // => [40, 50, 60]
Ajouter, mettre à jour et supprimer des éléments de tableau
En étudiant comment travailler avec des objets, nous avons appris les fonctions assoc
, dissoc
et omit
pour ajouter, mettre à jour et supprimer des propriétés.
Étant donné que les tableaux ont une structure de données ordonnée, nous avons plusieurs méthodes qui font le même travail que l' assoc
pour les objets. Les plus courants sont l' insertion et la mise à jour , mais Ramda fournit également des méthodes d' ajout et de pré- ajout pour les cas typiques d'ajout d'éléments au début et à la fin d'un tableau. insert
, append
et ajouter au prepend
ajouter de nouveaux éléments au tableau; update
"remplace" un élément spécifique du tableau par une nouvelle valeur.
Comme vous pouvez vous attendre d'une bibliothèque fonctionnelle, toutes ces fonctions renvoient un nouveau tableau avec les changements attendus; le tableau d'origine ne change jamais.
const numbers = [10, 20, 30, 40, 50, 60] insert(3, 35, numbers) // => [10, 20, 30, 35, 40, 50, 60] append(70, numbers) // => [10, 20, 30, 40, 50, 60, 70] prepend(0, numbers) // => [0, 10, 20, 30, 40, 50, 60] update(1, 15, numbers) // => [10, 15, 30, 40, 50, 60]
Pour combiner deux objets en un, nous avons précédemment appris la méthode de merge
. Ramda fournit également une méthode concat pour effectuer la même opération avec les tableaux.
const numbers = [10, 20, 30, 40, 50, 60] concat(numbers, [70, 80, 90]) // => [10, 20, 30, 40, 50, 60, 70, 80, 90]
Notez que le deuxième tableau a rejoint le premier. Cela semble logique lorsque vous utilisez cette méthode séparément des autres codes, mais, comme avec la merge
, cette logique peut ne pas conduire exactement à ce à quoi nous nous attendrions si nous utilisons cette méthode dans notre pipeline. J'ai trouvé utile d'écrire une fonction d'aide, concatAfter
: const concatAfter = flip(concat)
, pour l'utiliser dans mes pipelines.
Ramda propose également plusieurs options pour supprimer des éléments. remove supprime les éléments par leur index, tandis que without les supprime par leur valeur. Il existe également des méthodes telles que drop et dropLast pour les cas typiques lorsque nous supprimons des éléments du début ou de la fin d'un tableau.
const numbers = [10, 20, 30, 40, 50, 60] remove(2, 3, numbers) // => [10, 20, 60] without([30, 40, 50], numbers) // => [10, 20, 60] drop(3, numbers) // => [40, 50, 60] dropLast(3, numbers) // => [10, 20, 30]
Notez que remove
accepte un index et un montant, tandis que slice
accepte deux index. Cette incohérence peut être déroutante si vous ne la connaissez pas.
Conversion d'éléments
Comme pour les objets, nous pouvons souhaiter mettre à jour l'élément de tableau en appliquant la fonction à la valeur d'origine.
const numbers = [10, 20, 30, 40, 50, 60] // 10 update(2, multiply(10, nth(2, numbers)), numbers) // => [10, 20, 300, 40, 50, 60]
Pour simplifier ce cas typique, Ramda fournit une méthode d' ajustement qui fonctionne comme evolve
pour les objets. Mais contrairement à evolve
, adjust
fonctionne avec un seul élément du tableau.
const numbers = [10, 20, 30, 40, 50, 60] // 10 adjust(multiply(10), 2, numbers)
Notez que les deux premiers arguments à adjust
vont dans le sens inverse lorsque vous les comparez avec update
. Cela peut être une source d'erreurs, mais cela a du sens lorsque vous envisagez une application partielle. Vous pouvez faire un adjust(multiply(10))
par vous-même et décider ensuite quel index du tableau changer à l'aide de celui-ci.
Conclusion
Nous avons maintenant des outils pour travailler avec des tableaux et des objets dans un style déclaratif et immuable. Cela nous permet de construire des programmes composés de petits blocs fonctionnels, combinant des fonctions qui feront ce dont nous avons besoin, et tout cela sans changer toutes nos structures de données.
Suivant
Nous avons appris à lire, mettre à jour et transformer les propriétés des objets et des éléments de tableau. Ramda fournit d'autres outils de base pour effectuer ces opérations, les objectifs. Le prochain article sur l'objectif nous montrera comment ils fonctionnent.