likes
comments
collection
share

实现数组的map、filter、reduce方法

作者站长头像
站长
· 阅读数 26

用法简介

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
评论
请登录