参考资源:廖雪峰的官方网站

map()reduce()filter()sort()

map

  • 不会改变原数组

map() 方法定义在 JavaScript 的 Array 中,我们调用 Array 的 map() 方法,传入我们自己的函数,就得到了一个新的 Array 作为结果

  1. 'use strict';
  2. function pow(x) {
  3. return x*x;
  4. };
  5. var arr = [2,3,4];
  6. var result = arr.map(pow); // 数组的 map() 方法会返回一个新数组
  7. console.log(arr); //[2,3,4] 原数组不会改变
  8. console.log(result); //[4,9,16]

简单来说,就是把函数 pow() 作用到 Array 的每一个元素并把结果生成一个新的 Array

reduce

  • 不会改变原数组

Array 的 reduce() 方法把一个函数(此函数必须有两个参数 )作用在 Array 的每一项上,并把结果继续和序列的下一个元素做累计的运算。

来看几个简单的例子:

对一个 Array 求和

  1. 'use strict';
  2. function add (x,y) {
  3. return x+y;
  4. }
  5. var arr = [2,3,4];
  6. var result = arr.reduce(add);
  7. console.log(arr); //[2,3,4] 原数组不会改变
  8. console.log(result); //9

利用 reduce() 求积

  1. function product(arr) {
  2. return arr.reduce(function (x, y) { // reduce()接收一个必须包含两个参数的函数
  3. return x*y;
  4. });
  5. }
  6. product([2,3,4]); // 24

不要使用JavaScript内置的parseInt()函数,利用map和reduce操作实现一个string2int()函数:

  1. 'use strict';
  2. function string2int(s) {
  3. var arr = s.split(""); //分割字符串
  4. var numArr = arr.map(function (str) {
  5. return +str; //利用 + 将 str 转换为 number 类型
  6. });
  7. return numArr.reduce(function (x,y) {
  8. return x*10 + y;
  9. });
  10. }

请把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']

  1. // 1 利用 map 回调函数的参数和字符串的 substring 方法
  2. function normalize(arr) {
  3. return arr.map(function (ele) {
  4. return ele[0].toUpperCase() + ele.substring(1).toLowerCase();
  5. });
  6. }
  1. // 2 啰嗦一点的方法
  2. 'use strict';
  3. function normalize(arr) {
  4. var newArr = arr.map(function (str) {
  5. return str.toLowerCase(); //把数组中的每一项改为全部字母小写
  6. });
  7. return newArr.map(function (ele) {
  8. var result = ele.split(""); //把小写字母组成的字符串分割
  9. result[0] = result[0].toUpperCase(); //修改第一个字符为大写
  10. return result.join(""); //拼合字符串
  11. });
  12. }

小明希望利用map()把字符串变成整数:

  1. 'use strict';
  2. var arr = ['1', '2', '3'];
  3. var r;
  4. r = arr.map(parseInt);
  5. console.log(r); // 1,NaN,NaN

这里就要对 map() 的回调函数的参数有更为详细的了解。

由于map()接收的回调函数可以有3个参数:callback(currentValue, index, array),通常我们仅需要第一个参数,而忽略了传入的后面两个参数。不幸的是,parseInt(string, radix)没有忽略第二个参数,导致实际执行的函数分别是:

  • parseInt(‘0’, 0); // 0, 按十进制转换
  • parseInt(‘1’, 1); // NaN, 没有一进制
  • parseInt(‘2’, 2); // NaN, 按二进制转换不允许出现2

可以改为r = arr.map(Number);,因为Number(value)函数仅接收一个参数。

参考:Array.prototype.map()的文档

当然也可以改为:

  1. 'use strict';
  2. var arr = ['1', '2', '3'];
  3. var r;
  4. r = arr.map(function (x) {
  5. return parseInt(x);
  6. });
  7. console.log(r); // 1,2,3

filter

  • 不会改变原数组

  • 用于把 Array 的某些元素过滤掉。

filter() 接收一个函数,它会把传入的函数依次作用于每个元素,然后根据返回值是 true 还是 false 决定保留还是丢弃该元素。

在一个 Array 中,删掉偶数,只保留奇数:

  1. var arr = [1, 2, 4, 5, 6, 9, 10, 15];
  2. var r = arr.filter(function (num) {
  3. return num%2 !== 0;
  4. });
  5. console.log(r); //[1, 5, 9, 15]

把一个 Array 中的空字符串删掉:

  1. var arr = ['A', '', 'B', null, undefined, 'C', ' '];
  2. var r = arr.filter(function (s) {
  3. return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
  4. });
  5. r; // ['A', 'B', 'C']

filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身。

利用 filter() 巧妙地去除 Array 的重复元素:

  1. var
  2. r,
  3. arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
  4. r = arr.filter(function (ele, index, self) {
  5. return self.indexOf(ele) === index;
  6. });
  7. console.log(r); // ["apple", "strawberry", "banana", "pear", "orange"]

去除重复元素依靠的是indexOf总是返回第一个元素的位置,后续的重复元素位置与indexOf返回的位置不相等,因此被filter滤掉了。

请尝试用 filter() 筛选出素数:

  1. //质数又叫素数,定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
  2. function get_primes(arr) {
  3. var r = arr.filter(function (x, index, self) {
  4. if (x <= 1) {
  5. return false;
  6. }
  7. if (x === 2) { return true}
  8. else { //x大于2的情况
  9. for (let i = 2; i<x; i++) {
  10. if (x%i === 0) { //求余为0则该 i 值为 x 的因数
  11. return false;
  12. }
  13. }
  14. return true;
  15. }
  16. });
  17. return r;
  18. }
  19. var arr = [1,2,3,4,5,6,7,8,9,10,44,55,11];
  20. console.log(get_primes(arr)); // [2, 3, 5, 7, 11]

这是我自己根据素数的定义想出来的解决办法,应该还有很多更好的方法。

sort

  • 会改变原数组

Arraysort()方法默认把所有元素先转换为String再排序,所以会出现一些奇怪的现象:

  1. var arr = [1,2,3,10,20,30];
  2. arr.sort();
  3. arr; // [1, 10, 2, 20, 3, 30]

sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序

  1. var arr = [1,30,50,10,3,5];
  2. arr.sort(function (x,y) {
  3. if (x<y) {
  4. return -1;
  5. }
  6. if (x === y) {
  7. return 0;
  8. }
  9. else {
  10. return 1;
  11. }
  12. });
  13. console.log(arr); // [1, 3, 5, 10, 30, 50]

参考:Array.prototype.sort()

(完)