Tableaux en compréhension avec JavaScript

Tableaux en compréhension avec JavaScript

Une liste en compréhension est le résultat d'un fonction appliquée à une liste, qui filtre ou modifie ses éléments pour produire une nouvelle liste.

JavaScript depuis la versions 1.6 dispose de plusieurs fonctions qui mettent en pratique ce principe et permettent ainsi de simplifier le code. D'autres encore sont apparues dans les version suivantes du standard ECMAScript. Elle sont toutes compatibles avec Internet Explorer depuis la version 9, et tous les autres navigateurs récents.

La fonction que l'on appelle en callback peut n'avoir qu'un seul argument, qui un élément du tableau. Mais elle peut aussi avoir deux autres arguments: l'indice de l'élément dans le tableau, et une référence au tableau lui-même.

Exemples de callbacks valides:

Avec un seul argument, on peut lire le contenu du tableau:

function f(element) {
  document.write(element)
}

Et éventuellement retourner une valeur qui sera ajoutée à un tableau généré:

function f(element) {
  return(element * 2)
}

Avec les trois arguments on peut aussi lire le tableau original:

function f(element, index, arr) {
  document.write("arr[" + index + "]=" + element) 
}

Ou le modifier:

function f(element, index, arr) {
  arr[index] = element * 2 
}

Rapellons qu'un tableau est toujours passé par référence et non copié en tant qu'argument d'une fonction. Il est donc possible de modifier le tableau original avec une fonction en compréhension.

Fonctions qui produisent automatiquement un nouveau tableau

Map (1.6)

Crée un nouveau tableau dont les éléments sont ceux du tableau d'origine auxquels on a appliqué une fonction en paramètre.

var map1 = [ 1,2,3,4,5]
function fmap(x) {
  return x * 10
}
document.write("Original: ", map1)
document.write("Final: ", map1.map(fmap));

Filter (1.6)

Génère un nouveau tableau en appliquant la fonction donnée à chaque élément du tableau initial. La fonction en callback retourne vrai ou faux, si elle retourne vrai, l'élément du tableau original est ajouté au nouveau tableau généré.

L'exemple ci-dessous extrait la liste des nombres impairs à partir d'une liste de nombre pairs et impairs.

var filter1 = [1,2,3,4,5,6,7,8]
function ffil(x) {
  return x == (Math.round(x / 2) * 2)
}
document.write("Original: ", filter1)
document.write("Final: ", filter1.filter(ffil));

Reduce (1.8)

Applique une fonction a deux valeurs du tableau à la fois, de gauche à droite, pour les réduire a une seule valeur. La fonction s'applique entre l'élement 1 et l'élément 2, puis entre le résultat et l'élement 3, et ainsi de suite jusqu'au dernier élément du tableau.

Contrairement à filter, la fonction doit avoir deux arguments outre les arguments optionnels que sont l'indice et la référence au tableau. Dans l'exemple ci-dessous les on multiplie les deux premiers éléments et le résultat par chaque élément suivant. On obtient 120 qui est bien le produit de 1 par 2 par 3 etc... jusqu'à 5.

var reduce1 = [ 1,2,3,4,5]
function fred(x, y) {
  return x * y
}
document.write("Original: ", reduce1)
document.write("Final: ", reduce1.reduce(fred));

Reduce retournera un tableau si la fonction en callback retourne un tableau.

ReduceRight (1.8)

Applique une fonction a deux valeurs du tableau à la fois, de droite à gauche, pour les réduire a une seule valeur. Fait la même chose que reduce, mais en commençant par les dernier élément du tableau pour finir par le premier. L'exemple précédent donnerait le même résultat, mais cela peut être différent selon la fonction.

Ces deux méthodes peuvent s'utiliser aussi pour réaliser la somme des valeurs contenues dans un tableau et dispensent donc d'une méthode sum. On peut réaliser des opérations plus complexes comme transformer tableau à deux dimension en tableau à une dimension (exemple fourni par Mozilla): il suffit que la fonction concaténe les deux élements en paramètre.

Fonction qui modifie seulement le tableau d'origine

ForEach (1.7)

Appelle une fonction avec chaque élément du tableau successivement. Contrairement à every, cela ne produit pas un nouveau tableau.

L'exemple ci-dessous ajoute 10 à chaque nombre du tableau original. Cela ne fonctionne pas avec un seul argument, car contrairement à map, forEach ne génère pas un nouveau tableau.

var each1 = [ 1,2,3,4,5,6,7,8]
function efun(x) {
  return x + 10
}
document.write("Original: ", each1)
var result = each1.forEach(efun)
document.write("Final: ", result);

En utilisant trois arguments on peut modifier le tableau original:

var each2 = [ 1,2,3,4,5,6,7,8]
function efun2(x, idx, arr) {
	arr[idx] = x + 10
}
document.write("Avant: ", each2)
each2.forEach(efun2)
document.write("Après: ", each2);

Fonctions qui testent le contenu d'un tableau et retournent vrai ou faux

Every (1.6)

Retourne vrai si chaque élément du tableau satisfait la propriété fournie en condition.

La différence avec map est que l'on ne retourne pas un élément à ajouter au nouveau tableau, on retourne vrai ou faux pour l'ensemble du tableau: vrai si tous les éléments satisfont la condition, faux si un seul ne la satisfait pas.

var every1 = [ "un", "deux", "trois", "quatre", "cinq"]
function fever(x) {
  return (x.length <= 4) 
}
document.write("Original: ", every1)
document.write("Final: ", every1.every(fever));

Some (1.6)

Retourne vrai si au moins un élément du tableau satisfait la condition donnée.

var some1 = [ "un", "deux", "trois", "quatre", "cinq"]
function sever(x) {
  return (x.length <= 4) 
}
document.write("Original: ", some1)
document.write("Final: ", some1.some(sever));
© 30 juillet 2014 Xul.fr