一个函数接收另一个函数作为参数,这种函数就称之为高阶函数。
接收的函数称为回调函数。
Array对象提供的实用的高阶函数:
1. map
调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果
【不改变原数组】
可以接收的参数:元素,元素的位置,数组本身:
arr.map(function (element, index, self)
应用 1️⃣ :把Array的所有数字转为字符串
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
2. reduce
Array中的reduce()把结果继续和序列的下一个元素做 累积计算
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
回调函数接受四个参数。
1: 叠加器,它是上一次迭代中回调函数的返回值,
2: 当前正在处理的数组元素,
3: 该参数的索引,
4:在其上调用 reduce 方法的数组
除了回调函数,reduce 还有一个额外的参数做为叠加器的初始值。
如果没有第二个参数,会跳过第一次迭代,第二次迭代给叠加器传入数组的第一个元素。
【不改变原数组】
应用 1️⃣ :reduce求和
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
3. map/reduce练习
练习 1️⃣ :利用map和reduce操作实现一个string2int()函数
( 字符串转数字:1. 字符前加“+”
2. s *= 1;
)
function string2int(s) {
let arr=s.split("");
let arrNew=arr.map(item=>{
return +item; //字符串转数字
})
let res=arrNew.reduce((x,y)=>{
return x*10+y;
})
return res;
}
练习 2️⃣ :首字母大写,其他小写的规范名字
function normalize(arr) {
return arr.map(item=>{
item=item.toLowerCase();
item=item.replace(item.charAt(0),item.charAt(0).toUpperCase());
return item;
})
}
练习 3️⃣ :利用map()把字符串变成整数
var arr = ['1', '2', '3'];
var r;
//默认parseInt参数为item(键值对=>两个参数)
//第一次:parseInt(1, 0)``0 会调用默认 10 进制,因此返回 1。
//第二次:parseInt(2, 1)``radix 为 1,不在范围内,错误返回 NaN。
//第三次:parseInt(3, 2)``radix 为 2,在范围内,二进制范围是 0-1超过范围,错误返回 NaN
r = arr.map(item=>{
return parseInt(item);
});
4. filter
用于把Array的某些元素过滤掉,然后返回剩下的元素
filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
【不改变原数组】
应用 1️⃣ :把一个Array中的空字符串删掉
var r = arr.filter(function (s) {
return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
});
可以接收的参数:元素,元素的位置,数组本身:
arr.filter(function (element, index, self)
应用 2️⃣ :去除重复元素
r = arr.filter(function (element, index, self) {
return self.indexOf(element) === index;
});
应用 3️⃣ :用filter()筛选出素数
function get_primes(arr) {
return arr.filter(function(v){
if(v==1){return false}
for(var i=2;i<v;i++){
if(v%i==0) return false;
}
return true;
})
}
5. sort
Array的sort()方法默认把所有元素先转换为String再排序,字符串根据ASCII码进行排序。
- 小写字母的ASCII码在大写字母之后。
- '10’排在了’2’的前面,因为字符’1’比字符’2’的ASCII码小。
【不能直接对数字排序】
通常规定,对于两个元素x和y,
如果认为x < y, 则返回-1,
如果认为x == y,则返回0,
如果认为x > y, 则返回1。
(这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。)
应用 1️⃣ :按数字大小排序
arr.sort(function (x, y) {
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
return 0;
});
-
倒序排序:x < y 和 x > y互换
-
忽略大小写 :实际上就是先把字符串都变成大写(或者都变成小写),再比较。
-
sort()方法是直接对Array进行修改
6. every
every()方法可以判断数组的所有元素是否满足测试条件。
【不改变原数组】
console.log(arr.every(function (s) {
return s.toLowerCase() === s;
})); // false, 因为不是每个元素都全部是小写
7. find
find()方法用于查找符合条件的第一个元素,如果找到了,返回这个元素,否则,返回undefined。
【不改变原数组】
var arr = ['Apple', 'pear', 'orange'];
console.log(arr.find(function (s) {
return s.toLowerCase() === s;
})); // 'pear', 因为pear全部是小写
console.log(arr.find(function (s) {
return s.toUpperCase() === s;
})); // undefined, 因为没有全部是大写的元素
8. findIndex
和find()类似,也是查找符合条件的第一个元素,
不同之处在于findIndex()会返回这个元素的索引,如果没有找到,返回-1
【不改变原数组】
9. forEach
forEach()和map()类似,它也把每个元素依次作用于传入的函数,但不会返回新的数组。
forEach()常用于遍历数组,因此,传入的函数不需要返回值
var arr = ['Apple', 'pear', 'orange'];
arr.forEach(console.log); // 依次打印每个元素
- return相当于for中的continue
- break与return都无法跳出循环,需要使用抛出异常(try…catch)的方式跳出循环
10.数组扁平化
嵌套数组扁平化成一维数组。 必须考虑到各种深度的嵌套层级。
function steamrollArray(arr) {
let newArr=[];
arr.forEach(item=>{
if(Array.isArray(item)){
newArr=newArr.concat(...steamrollArray(item))
}else
newArr.push(item);
})
return newArr;
}
// test here
steamrollArray([1, [2], [3, [[4]]]]); // [1,2,3,4]