reduce的一点小理解


前阵子在项目中有用到 reduce() 方法,当时不是很理解,后来空了学习了一下,有了一点小收获,记之~

用法

Array.prototype.reduce() 方法对数组中的每个元素执行指定回调函数,将其结果汇总为单个返回值。这个方法接收两个参数:

  • 回调函数(必选),执行数组中每个值 (如果没有提供初始值则第一个值除外)的函数,包含四个参数:

    • accumulator(累计器),累计回调的返回值,值为上一次调用回调时返回的累积值或者初始值

    • currentValue,数组中正在处理的元素

    • index,数组中正在处理的当前元素的索引。如果提供了初始值,则起始索引号为0,否则从索引1起始

    • array,调用reduce()的数组,即源数组

  • 初始值(可选),作为第一次调用回调函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce() 将报错

[1,2,3].reduce((accumulator, currentValue) => {
  return accumulator + currentValue
})
// 1 + 2 + 3
// 6

[1,2,3].reduce((accumulator, currentValue) => {
  return accumulator + currentValue
}, 1)
// 1 + 1 + 2 + 3
// 7

[].reduce((accumulator, currentValue) => {
  return accumulator + currentValue
})
// 报错
// Uncaught TypeError: Reduce of empty array with no initial value
// at Array.reduce (<anonymous>)
// at <anonymous>:1:4

filter/find/forEach/map/reduce 的对比

这几个方法我总是会混淆,列了个表格方便对比

方法名 描述 语法 参数1 参数2 返回值
filter 返回满足所提供回调函数筛选条件的所有元素或空数组 var newArray = arr.filter(callback(element[, index[, array]])[, thisArg]) 用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数:
element 当前遍历到的元素
index可选 当前遍历到的索引
array可选 数组本身
执行回调时用作this 的对象 一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组
find 返回满足所提供回调函数筛选条件的第一个元素的值或 undefined arr.find(callback(element[, index[, array]])[, thisArg]) 在数组每一项上执行的函数,它接受以下三个参数:
element 当前遍历到的元素
index可选 当前遍历到的索引
array可选 数组本身
执行回调时用作this 的对象 数组中第一个满足所提供测试函数的元素的值,否则返回 undefined
forEach 对数组的每个元素执行一次提供的回调函数 arr.forEach(callback(currentValue [, index [, array]])[, thisArg]) 为数组中每个元素执行的函数,它接受以下三个参数:
element 当前遍历到的元素
index可选 当前遍历到的索引
array可选 数组本身
执行回调时用作this 的对象 undefined
map 返回数组中的每个元素调用一次提供的函数后组合形成的新数组 var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
生成新数组元素的函数,它接受以下三个参数:
element 当前遍历到的元素
index可选 当前遍历到的索引
array可选 数组本身
执行回调时用作this 的对象 一个由原数组每个元素执行回调函数的结果组成的新数组
reduce 返回数组中的每个元素升序调用一次提供的函数后汇总而成的值 arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) 执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,它接受以下四个参数:
accumulator 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue
element 当前遍历到的元素
index可选 当前遍历到的索引
array可选 数组本身
作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素 函数累计处理的结果

使用 reduce 实现 filter

if (!Array.prototype.filterUsingReduce) {
  Array.prototype.filterUsingReduce = function(callback, thisArg) {
    return this.reduce(function(filterArray, currentValue, index, array) {
      if (callback.call(thisArg, currentValue, index, array)) {
        filterArray.push(currentValue)
      }
      return filterArray
    }, [])
  }
}

[1, 4, 9, 16].filterUsingReduce(
  (currentValue) => currentValue > 10
) // [16]

使用 reduce 实现 find

if (!Array.prototype.findUsingReduce) {
  Array.prototype.findUsingReduce = function(callback, thisArg) {
    return this.reduce(function(findArray, currentValue, index, array) {
      if (callback.call(thisArg, currentValue, index, array)) {
        if (findArray instanceof Array && findArray.length === 0) {
        findArray = currentValue
        }
      }
      if ((index === array.length - 1) && findArray instanceof Array && findArray.length === 0) {
        findArray = undefined
      }
      return findArray
    }, [])
  }
}

[1, 4, 9, 16].findUsingReduce(
  (currentValue) => currentValue % 2 === 0
) // [4]

使用 reduce 实现 forEach

if (!Array.prototype.forEachUsingReduce) {
  Array.prototype.forEachUsingReduce = function(callback, thisArg) {
    this.reduce(function(forEachArray, currentValue, index, array) {
      callback.call(thisArg, currentValue, index, array)
    }, [])
  }
}
const array1 = ['a', 'b', 'c'];
array1.forEachUsingReduce(element => console.log(`${element}: ${element+1}`));
// a: a1
// b: b1
// c: c1

使用 reduce 实现 map

if (!Array.prototype.mapUsingReduce) {
  Array.prototype.mapUsingReduce = function(callback, thisArg) {
    return this.reduce(function(mappedArray, currentValue, index, array) {
      mappedArray[index] = callback.call(thisArg, currentValue, index, array)
      return mappedArray
    }, [])
  }
}

[1, 4, 9, 16].mapUsingReduce(
  (currentValue, index, array) => currentValue + index + array.length
) // [5, 9, 15, 23]

参考文章:

自从学会了 Array.reduce() ,再也离不开它

以前我没得选,现在我只想用 Array.prototype.reduce

生动形象解释forEach、filter、map、some、every、find、findIndex、reduce间的区别


文章作者: April-cl
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 April-cl !
  目录