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

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

map

  • 不会改变原数组

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

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

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

reduce

  • 不会改变原数组

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

来看几个简单的例子:

对一个 Array 求和

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

利用 reduce() 求积

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

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

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

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

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

}

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

'use strict';
var arr = ['1', '2', '3'];
var r;
r = arr.map(parseInt);
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()的文档

当然也可以改为:

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

filter

  • 不会改变原数组

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

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

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

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

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

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

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

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

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

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

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

//质数又叫素数,定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
function get_primes(arr) {
  var r = arr.filter(function (x, index, self) {
    if (x <= 1) {
      return false;
    }
    if (x === 2) { return true}
    else {  //x大于2的情况
      for (let i = 2; i<x; i++) {
        if  (x%i === 0) { //求余为0则该 i 值为 x 的因数
          return false;
        }
      }
      return true;
    }
  });
  return r;
}

var arr = [1,2,3,4,5,6,7,8,9,10,44,55,11];
console.log(get_primes(arr)); // [2, 3, 5, 7, 11]

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

sort

  • 会改变原数组

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

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

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

var arr = [1,30,50,10,3,5];
arr.sort(function (x,y) {
  if (x<y) {
    return -1;
  }
  if (x === y) {
    return 0;
  }
  else {
    return 1;
  }
});

console.log(arr);  // [1, 3, 5, 10, 30, 50]

参考:Array.prototype.sort()

(完)