The array comprehensions syntax is non-standard and removed starting with Firefox 58. For future-facing usages, consider using

`Array.prototype.map`

, `Array.prototype.filter`

, arrow functions, and spread syntax.The **array comprehension** syntax was a JavaScript expression which allowed you to quickly assemble a new array based on an existing one. However, it has been removed from the standard and the Firefox implementation. Do not use it!

[for (x of iterable) x] [for (x of iterable) if (condition) x] [for (x of iterable) for (y of iterable) x + y]

Inside array comprehensions, these two kinds of components are allowed:

The for-of iteration is always the first component. Multiple for-of iterations or if statements are allowed.

Array comprehension was previously proposed to be standardized in ECMAScript 2016, it provide a useful shortcut for constructing a new array based on the contents of another. Comprehensions can often be used in place of calls to `map()`

and `filter()`

, or as a way of combining the two.

The following comprehension takes an array of numbers and creates a new array of the double of each of those numbers.

var numbers = [1, 2, 3, 4]; var doubled = [for (i of numbers) i * 2]; console.log(doubled); // logs 2,4,6,8

This is equivalent to the following `map()`

operation:

var doubled = numbers.map(i => i * 2);

Comprehensions can also be used to select items that match a particular expression. Here is a comprehension which selects only even numbers:

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

`filter()`

can be used for the same purpose:

var evens = numbers.filter(i => i % 2 === 0);

`map()`

and `filter()`

style operations can be combined into a single array comprehension. Here is one that filters just the even numbers, then creates an array containing their doubles:

var numbers = [1, 2, 3, 21, 22, 30]; var doubledEvens = [for (i of numbers) if (i % 2 === 0) i * 2]; console.log(doubledEvens); // logs 4,44,60

The square brackets of an array comprehension introduce an implicit block for scoping purposes. New variables (such as i in the example) are treated as if they had been declared using `let`

. This means that they will not be available outside of the comprehension.

The input to an array comprehension does not itself need to be an array; iterators and generators can also be used.

Even strings may be used as input; to achieve the filter and map actions (under Array-like objects) above:

var str = 'abcdef'; var consonantsOnlyStr = [for (c of str) if (!(/[aeiouAEIOU]/).test(c)) c].join(''); // 'bcdf' var interpolatedZeros = [for (c of str) c + '0' ].join(''); // 'a0b0c0d0e0f0'

Again, the input form is not preserved, so we have to use `join()`

to revert back to a string.

[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"]

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]

`map`

and `filter`

An easy way to understand array comprehension syntax, is to compare it with the Array `map`

and `filter`

methods:

var numbers = [1, 2, 3]; numbers.map(function (i) { return i * i }); numbers.map(i => i * i); [for (i of numbers) i * i]; // all are [1, 4, 9] numbers.filter(function (i) { return i < 3 }); numbers.filter(i => i < 3); [for (i of numbers) if (i < 3) i]; // all are [1, 2]

Using two for-of iterations to work with two 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"]]

Was initially in the ECMAScript 2015 draft, but got removed in revision 27 (August 2014). Please see older revisions of ES2015 for specification semantics.

Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|

Basic support | No | No | 30 — 58 | No | No | No |

Feature | Android webview | Chrome for Android | Edge mobile | Firefox for Android | Opera Android | iOS Safari | Samsung Internet |
---|---|---|---|---|---|---|---|

Basic support | No | No | No | 30 — 58 | No | No | ? |

JS1.7/JS1.8 comprehensions are removed from Gecko starting with version 46 (bug 1220564).

**Old comprehensions syntax (do not use anymore!):**

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

Differences:

- ESNext comprehensions create one scope per "for" node instead of the comprehension as a whole.
- Old:
`[()=>x for (x of [0, 1, 2])][1]() // 2`

- New:
`[for (x of [0, 1, 2]) ()=>x][1]() // 1, each iteration creates a fresh binding for x.`

- Old:
- ESNext comprehensions start with "for" instead of the assignment expression.
- Old:
`[i * 2 for (i of numbers)]`

- New:
`[for (i of numbers) i * 2]`

- Old:
- ESNext comprehensions can have multiple
`if`

and`for`

components. - ESNext comprehensions only work with

and not with`for...of`

iterations.`for...in`

See Bug 1220564, comment 42 for suggestions on updating code.

© 2005–2018 Mozilla Developer Network and individual contributors.

Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Array_comprehensions