The array comprehension syntax is a JavaScript expression which allows you to quickly assemble a new array based on an existing one. Comprehensions exist in many programming languages and the upcoming ECMAScript 7 standard defines array comprehensions for JavaScript.
See below for differences to the old array comprehension syntax in SpiderMonkey, based on proposals for ECMAScript 4.
Syntax
[for (x of iterable) x] [for (x of iterable) if (condition) x] [for (x of iterable) for (y of iterable) x + y]
Description
Inside array comprehensions, these two kinds of components are allowed:
- {{jsxref("Statements/for...of", "for...of")}} and
- {{jsxref("Statements/if...else", "if")}}
The for-of iteration is always the first component. Multiple for-of iterations or if statements are allowed.
Examples
Simple array comprehensions
[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 with if statement
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 compared to map
and filter
An easy way to understand array comprehension syntax, is to compare it with the Array {{jsxref("Array.map", "map")}} and {{jsxref("Array.filter", "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 ]
Array comprehensions with two arrays
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"]]
Specifications
{{WhyNoSpecStart}}Was initially in the ECMAScript 6 draft, but got removed in revision 27 (August 2014). Please see older revisions of ES 6 for specification semantics. An updated version is expected to be in a new ES2016 / ES7 draft.{{WhyNoSpecEnd}}
Browser compatibility
{{CompatibilityTable}}
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | {{CompatNo}} | {{ CompatGeckoDesktop("30") }} | {{CompatNo}} | {{CompatNo}} | {{CompatNo}} |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | {{CompatNo}} | {{CompatNo}} | {{ CompatGeckoMobile("30") }} | {{CompatNo}} | {{CompatNo}} | {{CompatNo}} |
SpiderMonkey-specific implementation notes
- {{jsxref("Statements/let", "let")}} as an identifier is not supported as
let
is currently only available to JS version 1.7 and XUL scripts tags. - Destructuring in comprehensions is not supported yet ({{bug(980828)}}).
Differences to the older JS1.7/JS1.8 comprehensions
- ES7 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:
- ES7 comprehensions start with "for" instead of the assignment expression.
- Old:
[i * 2 for (i of numbers)]
- New:
[for (i of numbers) i * 2]
- Old:
- ES7 comprehensions can have multiple
if
andfor
components. - ES7 comprehensions only work with
{{jsxref("Statements/for...of", "for...of")}}
and not with{{jsxref("Statements/for...in", "for...in")}}
iterations.
See also
- {{jsxref("Statements/for...of", "for...of")}}
- {{jsxref("Operators/Generator_comprehensions", "Generator comprehensions", "" ,1)}}