Compréhensions de tableau

Non-standard. Ne pas utiliser !
Les compréhensions de tableau ne sont pas standard. Il est peu probable qu'elles soient ajoutées à ECMAScript. Pour obtenir des fonctionnalités équivalentes, il est conseillés d'utiliser Array.prototype.map, Array.prototype.filter, les fonctions fléchées et ladécomposition.

Cette fonctionnalité fait partie des propositions pour Harmony (ECMAScript7) et est donc expérimentale.
Cette spécification technique n'a pas encore été stabilisée, veuillez consulter le tableau de compatibilité pour plus d'informations sur les éventuelles différences entre les navigateurs. Il convient de noter qu'une fonctionnalité expérimentale peut voir sa syntaxe ou son comportement modifié dans le futur, en fonction des évolutions de la spécification.

La syntaxe de compréhension de tableau est une expression JavaScript permettant de construire rapidement un nouveau tableau à partir d'un tableau existant. Ces compréhensions existent dans de nombreux langages de programmation et le standard à venir ECMAScript 7 définit les compréhension de tableaux en JavaScript.

Voir ci-après les différences avec l'ancienne syntaxe SpiderMonkey, basée sur les propositions d'ECMAScript 4.

Syntaxe

[for (x of itérable) x]
[for (x of itérable) if (condition) x]
[for (x of itérable) for (y of itérable) x + y]

Description

Dans une compréhension de tableau, on peut utiliser deux types de composants :

L'itération basée sur for...of sera toujours le premier composant. On peut utiliser plusieurs for...of ou instructions if.

Les compréhensions de tableau furent proposées pour être standardisées avec ECMAScript 7. Elles fournissent une notation raccourcie pour pouvoir construire un nouveau tableau basé sur le contenu d'un autre tableau. Les compréhensions sont proches des fonctions map() et filter() qui peuvent être combinées pour arriver au même effet.

La compréhension qui suit prend un tableau de nombres et crée un nouveau tableau qui contiendra les doubles de chaque élément :

var nombres = [1, 2, 3, 4];
var doublés = [for (i of nombres) i * 2];
console.log(doublés); // affiche 2,4,6,8

Cela est équivalent à l'opération suivante, qui utilise map() :

var doublés = nombres.map(i => i * 2);

Les compréhensions peuvent également être utilisées pour sélectionner certains éléments qui respectent un critère donné. Voici par exemple une compréhension qui ne sélectionne que les nombres pairs :

var nombres = [1, 2, 3, 21, 22, 30];
var pairs = [for (i of nombres) if (i % 2 === 0) i];
console.log(pairs); // affiche 2,22,30

Ici, la méthode filter() peut être utilisée pour parvenir au même résultat :

var pairs = nombres.filter(i => i % 2 === 0);

map() et filter() peuvent être utilisés pour traduire une compréhension de tableau.

Voici un autre exemple de compréhension, qui ne prend que les nombres pairs et qui les double :

var nombres = [1, 2, 3, 21, 22, 30];
var pairsDoublés = [for (i of nombres) if (i % 2 === 0) i * 2];
console.log(pairsDoublés); // affiche 4,44,60

Les crochets d'une compréhension introduisent un bloc implicite pour les portées. Les nouvelles variables (comme i dans l'exemple), sont traitées comme si elles avaient été déclarées avec let. Cela signifie donc que ces variables ne pourront pas être utilisées en dehors de la compréhension.

L'élément d'entrée d'une compréhension de tableau ne doit pas nécessairement être un tableau, il est également possible d'utiliser des itérateurs et des générateurs.

Une chaîne de caractères peut aussi être utilisé comme élément de départ :

var str = 'abcdef';
var consonnes = [for (c of str) if (!(/[aeiouyAEIOUY]/).test(c)) c].join(''); // 'bcdf'
var avecZéros = [for (c of str) c+'0' ].join(''); // 'a0b0c0d0e0f0'

Là encore, la structure de l'élément d'entrée n'est pas préservée, il faut donc utiliser join() pour récupérer une chaîne.

Exemples

Compréhensions de tableaux simples

[for (i of [ 1, 2, 3 ]) i*i ]; 
// [ 1, 4, 9 ]

var abc = [ "A", "B", "C" ];
[for (lettres of abc) lettres.toLowerCase()];
// [ "a", "b", "c" ]

Compréhensions de tableaux utilisant if

var années = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
[for (année of années) if (année > 2000) année];
// [ 2006, 2010, 2014 ]
[for (année of années) if (année > 2000) if(année < 2010) année];
// [ 2006] qui correspond aussi à 
[for (année of années) if (année > 2000 && année < 2010) année];
// [ 2006

Comparaison avec map et filter

Afin de mieux comprendre la syntaxe des compréhensions, on peut la comparer avec les méthodes de l'objet Array map et filter :

var nombres = [ 1, 2, 3 ];

nombres.map(function (i) { return i * i });
nombres.map(i => i*i);
[for (i of nombres) i*i ];
// tous vaudront [ 1, 4, 9 ]

nombres.filter(function (i) { return i < 3 });
nombres.filter(i => i < 3);
[for (i of nombres) if (i < 3) i];
// on obtiendra [ 1, 2 ] pour ces trois instructions

Les compréhensions manipulant deux tableaux

On peut itérer deux fois avec for...of afin de travailler avec deux tableaux :

var nombres = [ 1, 2, 3 ];
var lettres = [ "a", "b", "c" ];

var produitCartésien = [for (i of nombres) for (j of lettres) i+j];
// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]

var grille = [for (i of nombres) [for (j of lettres) i+j]];
// [
//  ["1a", "1b", "1c"],
//  ["2a", "2b", "2c"],
//  ["3a", "3b", "3c"]
// ]

[for (i of nombres) if (i > 1) for (j of lettres) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"], correspond à :

[for (i of nombres) for (j of lettres) if (i > 1) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"]

[for (i of nombres) if (i > 1) [for (j of lettres) if(j > "a") i+j]]
// [["2b", "2c"], ["3b", "3c"]], ne correspond pas à :

[for (i of nombres) [for (j of lettres) if (i > 1) if(j > "a") i+j]]
// [[], ["2b", "2c"], ["3b", "3c"]]

Spécifications

Ce point faisait initialement partie du brouillon ECMAScript 6 mais fut retiré dans la révision 27 (août 2014). Veuillez vous référer aux révisions précédentes pour la sémantique utilisée.

Compatibilité des navigateurs

Fonctionnalité Chrome Firefox (Gecko) Internet Explorer Opera Safari
Support simple Pas de support 30 (30) Pas de support Pas de support Pas de support
Fonctionnalité Android

Chrome pour Android

Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Support simple Pas de support Pas de support 30.0 (30) Pas de support Pas de support Pas de support

Notes spécifiques relatives à l'implémentation de SpiderMonkey

  • let en tant qu'identifiant n'est plus supporté. let est seulement disponible pour JS 1.7 et les balises des scripts XUL.
  • La déconstruction des tableaux n'est pas encore supportée.

Différences avec les compréhensions précédentes JS1.7/JS1.8

Les compréhensions « JS1.7 / JS1.8 » ont été retirées à partir de Gecko 46 (bug 1220564).

Ancienne syntaxe pour les compréhensions (ne plus l'utiliser) :

[X for (Y in Z)]
[X for each (Y in Z)]
[X for (Y of Z)]

Les différences :

  • Les compréhensions ES7 créent une portée par nœud «for » au lieu d'une portée par compréhension.
    • Ancienne syntaxe : [()=>x for (x of [0, 1, 2])][1]() // 2
    • Nouvelle syntaxe : [for (x of [0, 1, 2]) ()=>x][1]() // 1, chaque itération crée une nouvelle liaison pour x.
  • Les compréhensions ES7 débutent avec "for" et non plus avec une expression d'assignation :
    • Ancienne syntaxe : [i * 2 for (i of nombres)]
    • Nouvelle syntaxe : [for (i of nombres) i * 2]
  • Les compréhensions ES7 peuvent comporter plusieurs composants if et for.
  • Les compréhensions ES7 ne fonctionnent qu'avec for...of et ne fonctionnent pas avec  for...in.

Pour quelques suggestions pour migrer du code, voir le bug bug 1220564 et notamment le commentaire #42.

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : SphinxKnight, teoli
 Dernière mise à jour par : SphinxKnight,