Array.prototype.reduce()

reduce() 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。

语法

arr.reduce(callback[, initialValue])

参数

  • callback 执行数组中每个值的函数,包含四个参数:
    • accumulator 累加器累加回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue
    • currentValue 数组中正在处理的元素。
    • currentIndex 可选,数组中正在处理的当前元素的索引。 如果提供了initialValue,则索引号为0,否则为索引为1。
    • array可选,调用 reduce 的数组。
  • initialValue 可选,用作第一个调用 callback 的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

返回值

函数累计处理的结果。

实际应用

使用 reduce 求最值

最大值

const max = arr => Array.prototype.reduce.call(arr, (pre, cur) => Math.max( pre, cur ))
// or
const max = arr => arr.reduce( (pre, cur) => Math.max(pre, cur) )
max([5,8,3,4,9,7]) // 9

最小值

const min = arr => Array.prototype.reduce.call(arr, (pre, cur) => Math.min( pre, cur ))
// or
const min = arr => arr.reduce( (pre, cur) => Math.min(pre, cur) )
min([5,8,3,4,9,7]) // 3

当然,其实求最值也没那么繁琐,上面代码只是为了掩饰 reduce 的作用,简单的方法为:

最大值

const arrayMax = arr => Math.max(...arr);
arrayMax([10, 1, 5]) // 10

最小值

const arrayMin = arr => Math.min(...arr);
arrayMin([10, 1, 5]) // 1

数组求和

const sum = arr => arr.reduce( (acc, cur) => acc + cur, 0 )
sum([5,6,8,4]) // 23

平铺二维数组

const flatten = arr => arr.reduce((a, v) => a.concat(v), []);
flatten([[0, 1], [2, 3], [4, 5]]) // [0, 1, 2, 3, 4, 5]
flatten([1,[2],3,4]) // [1,2,3,4]

统计数组中每个元素出现的次数

原理

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var countedNames = names.reduce((allNames, name) => {
  name in allNames ? allNames[name]++ : allNames[name] = 1
  return allNames
}, {}); // 这里使用一个空对象初始化
// {Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

封装

const countArrOccurrences = (arr) => arr.reduce( (all, cur) => {
  cur in all ? all[cur]++ : all[cur] = 1
  return all
}, {} )
countArrOccurrences(['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'])
// {Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

如果只统计指定的元素次数:

const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a, 0);
let name = ['Alice', 'Bob', 'Alice', 'Tiff', 'Bruce', 'Alice']
countOccurrences(name, 'Alice') // 3

提取指定元素

使用 reduce() 只 过滤/萃取 出 arr 参数指定 key (如果 key 存在于 obj 中)的属性值。

const pick = (obj, arr)
  => arr.reduce((acc, curr)
  => (curr in obj && (acc[curr] = obj[curr]), acc), {})
pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) // { 'a': 1, 'c': 3 }

使用扩展运算符和initialValue绑定包含在对象数组中的数组

var friends = [{
  name: 'Anna',
  books: ['Bible', 'Harry Potter'],
  age: 21
}, {
  name: 'Bob',
  books: ['War and peace', 'Romeo and Juliet'],
  age: 26
}, {
  name: 'Alice',
  books: ['The Lord of the Rings', 'The Shining'],
  age: 18
}]
var allbooks = friends.reduce(function(prev, curr) {
  return [...prev, ...curr.books]
}, ['Alphabet'])
// ["Alphabet", "Bible", "Harry Potter", "War and peace", "Romeo and Juliet", "The Lord of the Rings", "The Shining"]

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress