参考资源:廖雪峰的官方网站
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)
函数仅接收一个参数。
当然也可以改为:
'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
- 会改变原数组
Array
的sort()
方法默认把所有元素先转换为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]
(完)