Sumário
A sintaxe de array comprehension trata-se de uma expressão JavaScript que lhe permite rapidamente montar um novo array com base em outro já existente. As comprehensions já existem em várias outras linguagens e estarão então presentes no padrão ECMAScript 7.
Veja abaixo as diferenças para a antiga implementação no SpiderMOnkey, baseado nas propostas para o ECMAScript 4.
Sintaxe
[for (x of iterable) x] [for (x of iterable) if (condition) x] [for (x of iterable) for (y of iterable) x + y]
Descrição
Dentro de array comprehensions dois tipos de components são permitidos:
A iteração por for-of deve sempre, ser a primeira componente. Multiplos for-of
ou if
s podem também ser permitidos.
Exemplos
Array comprehensions simples
[for (i of [ 1, 2, 3 ]) i*i ];
// [ 1, 4, 9 ]
var abc = [ "A", "B", "C" ];
[for (letters of abc) letters.toLowerCase()];
// [ "a", "b", "c" ]
Array comprehensions com if
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
[for (year of years) if (year > 2000) year];
// [ 2006, 2010, 2014 ]
[for (year of years) if (year > 2000) if(year < 2010) year];
// [ 2006], the same as below:
[for (year of years) if (year > 2000 && year < 2010) year];
// [ 2006]
Array comprehensions comparado a map e filter
Um modo fácil de entender a sintaxe de array comprehension é comparar com os métodos map
e filter
:
var numbers = [ 1, 2, 3 ];
numbers.map(function (i) { return i * i });
[for (i of numbers) i*i ];
// both is [ 1, 4, 9 ]
numbers.filter(function (i) { return i < 3 });
[for (i of numbers) if (i < 3) i];
// both is [ 1, 2 ]
Array comprehensions com dois arrays
Utilizando dois iteradores for-of, com dois arrays:
var numbers = [ 1, 2, 3 ];
var letters = [ "a", "b", "c" ];
var cross = [for (i of numbers) for (j of letters) i+j];
// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]
var grid = [for (i of numbers) [for (j of letters) i+j]];
// [
// ["1a", "1b", "1c"],
// ["2a", "2b", "2c"],
// ["3a", "3b", "3c"]
// ]
[for (i of numbers) if (i > 1) for (j of letters) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"], the same as below:
[for (i of numbers) for (j of letters) if (i > 1) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"]
[for (i of numbers) if (i > 1) [for (j of letters) if(j > "a") i+j]]
// [["2b", "2c"], ["3b", "3c"]], not the same as below:
[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]]
// [[], ["2b", "2c"], ["3b", "3c"]]
Especificações
Specification | Status | Comment |
---|---|---|
Proposed for ECMAScript 7 | No draft available yet | Estava inicialmente no rascunho para o ES6, porém foi removido na revisão 27 (Agosto, 2014). Veja as revisões antigas do ES6 para especificações de semântica. Uma versão atualizada estará de volta em um novo rascunho do ES7. |
Compatibilidade
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | Não suportado | 30 (30) | Não suportado | Não suportado | Não suportado |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | Não suportado | Não suportado | 30.0 (30) | Não suportado | Não suportado | Não suportado |
Notas sobre implementações para o SpiderMonkey
let
como um idenficador não é suportado, assim let está recentemente disponível somente para JS versão 1.7 e tags de scripts XUL.- Destruturação em comprehensions ainda não é suportado (bug 980828).
Diferenças para as antiga JS1.7/JS1.8 comprehensions
- Comprehensions no ES7 criam um escopo para cada nó de for
ao invés da comprehension toda
- Antigo:
[()=>x for (x of [0, 1, 2])][1]() // 2
- Novo:
[for (x of [0, 1, 2]) ()=>x][1]() // 1, cada iteração cria uma nova binding para o
x.
- Antigo:
- Comprehensions no ES7 iniciam com
for
ao invés de expressão de assinalamento.- Antigo:
[i * 2 for (i of numbers)]
- Novo:
[for (i of numbers)
i * 2
]
- Antigo:
- Comprehensions no ES7 podem ter multiplos
if
efor
. - Comprehensions no ES7 funcionam apenas com
for...of
e não com iteraçõesfor...in.