数组推导式(Array comprehensions)
在JavaScript 1.7 被介绍并计划在 ECMAScript 7, array comprehensions 被规范化并提供一个有用的快捷方式,用来实现如何在另一个数组的基础上构造一个新的数组。推导式可以经常被用在那些需要调用 map()
和 filter()函数的地方,
或作为一种结合这两种方式。
下面的推导式创建一个数字数组并且创建一个新的数组,数组的每个元素都是原来数值的两倍(译者注:这种形式类似于Python的列表推导式)。
var numbers = [1, 2, 3, 4];
var doubled = [i * 2 for (i of numbers)];
console.log(doubled); // logs 2,4,6,8
这跟下面的map()方法的操作是等价的。
var doubled = numbers.map(function(i){return i * 2;});
推导式也可以用来筛选满足条件表达式的元素. 下面的推导式用来筛选是2的倍数的元素:
var numbers = [1, 2, 3, 21, 22, 30];
var evens = [i for (i of numbers) if (i % 2 === 0)];
console.log(evens); // logs 2,22,30
filter()
也可以达到相同的目的:
var evens = numbers.filter(function(i){return i % 2 === 0;});
map()
和filter()
类型的操作可以被组合(等效)为单个数组推导式。这里就有一个过滤出偶数,创建一个它的倍数数组的例子:
var numbers = [1, 2, 3, 21, 22, 30];
var doubledEvens = [i * 2 for (i of numbers) if (i % 2 === 0)];
console.log(doubledEvens); // logs 4,44,60
数组推导式隐含了块作用域。新的变量(如例子中的i)类似于是采用 let
声明的。这意味着他们不能在推导式以外访问。
数组推导式的输入不一定必须是数组; 迭代器和生成器 也是可以的。
甚至字符串也可以用来作为输入; 实现filter或者map行为 (参考上面类似数组行为的对象)如下:
var str = 'abcdef';
var consonantsOnlyStr = [c for (c of str) if (!(/[aeiouAEIOU]/).test(c)) ].join(''); // 'bcdf'
var interpolatedZeros = [c+'0' for (c of str) ].join(''); // 'a0b0c0d0e0f0'
不过,输入形式是不能保存的,所以我们要使用join()回复到一个字符串。