实现数组的map、filter、reduce方法
用法简介
map
作用
创建一个新数组,返回该数组中每个元素调用一次提供的函数后的返回值;
语法
let newArr = arr.map(function callback(curValue, index, array){}[, thisArg])
- callback: 要对每个元素执行的回调函数;
- curValue:数组中正在处理的元素;
- index:数组中正在处理元素的索引,可选;
- array:调用了map方法的数组,可选;
- thisArg:执行callback值值被用作this;
示例
下面用数组的map方法对数组做一些处理
//打印出数组每一项的age
let arr = [
{
name: 'youyan',
age: 1
},
{
name: 'shaoyan',
age: 10
},
{
name: 'xiaoyan',
age: 18
},
{
name: 'dayan',
age: 28
},
];
let ageArr = arr.map((item)=>item.age)
// 新的数组为: [1, 10, 18, 28]
filter
作用
过滤中通过指定函数测试的元素;
语法
let newArr = arr.filter(function callback(curValue, index, array){}[, thisArg])
- callback: 用来测试每个元素执行的回调函数,返回true表示通过测试,保留该元素;
- curValue:数组中正在处理的元素;
- index:数组中正在处理元素的索引,可选;
- array:调用了filter方法的数组,可选;
- thisArg:执行callback值值被用作this;
示例
// 过滤出数组中大于10的值
let arr = [1, 2, 5, 15, 190, 88, 63];
let newArr = arr.filter((item)=> item > 10);
// [15, 190, 88, 63]
reduce
作用
这是一个数组的归并方法,对给定的数组进行遍历,函数的第一个参数是迭代计算后结果。
语法
arr.reduce(callback, initValue)
- callback(pre, cur, index, arr): 要执行的函数
- pre: 上次调用函数的返回值
- cur:当前元素
- index:当前元素索引
- arr:被遍历的数组
- initValue: 函数迭代的初始值
如果没有提供initValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引,pre的默认值为数组的第一个元素。如果提供initValue,从索引0开始。
示例
来几个示例:
- 数组求和
//用reduce方法对数组进行求和
let arr = [1, 2, 3, 4]
arr.reduce((pre, cur)=>pre + cur);
-
数组扁平化
// 将[[1,2,3], [4,5,6], [7,8,9]] 扁平化 let arr = [[1,2,3], [4,5,6], [7,8,9]]; arr.reduce((pre,cur)=>{ return pre.concat(cur); }, [])
// 这里给linitValue为[],会从数组的索引为0开始执行callback,将每一项连接到数组后,作为下一次迭代的初始值
- 求数组中每个元素出现的次数
```javascript
let arr = ['1', '2', '2', '3', '1', '1', '4', '2', '5'];
arr.reduce((pre, cur)=>{
if(pre.hasOwnProperty(cur)){
pre[cur] ++;
} else {
pre[cur] = 1;
}
return pre;
}, {})
手动实现
map、filter、reduce 三个方法有均是Array原型上的方法。下面自己简单实现一下这几个方法:
map
// 实现我的map方法
Array.prototype.myMap = function(fn){
const res = [];
let arr = this; // 谁调用函数,this指向谁
for(let item of arr){
res.push(fn(item))
}
return res;
}
// 调用
let double = (v) => 2 * v;
let arr = [1, 2, 3, 4];
arr.myMap(double); // [2, 4, 6, 8] 验证通过
filter
Array.prototype.myFilter = function(fn) {
const res = [];
let arr = this;
for(let item of arr){
if(fn(item)){ //通过函数方法验证
res.push(item);
}
}
return res;
}
// 调用
let fn = (v) => v > 5;
let arr = [1, 3, 6, 8, 9];
arr.myFilter(fn); // [6, 8, 9]
reduce
Array.prototype.myReduce = function(...args){
let arr = this; // 调用这个方法的数组
let fn = args[0]; // 要调用的函数
let initValue, index; // 定义初始值
if(args.length > 1){
initValue = args[1];
index = 0;
} else {
initValue = arr[0];
index = 1;
}
let value = initValue;
for(let i=index, len = arr.length; i< len; i++){
//前面提到的,有默认值从第0项开始索引,没有默认值从第一项开始索引
value = fn(value, arr[i]);
}
return value;
}
//调用,无默认值
[1, 2, 3, 4].myReduce((pre, cur) => pre + cur) // 10
// 有默认值
[1, 2, 3, 4].myReduce((pre, cur) => pre + cur, 10) // 20
转载自:https://juejin.cn/post/6876628174906589191