Array.prototype.reduce() 的简单使用 (续...)

reduce()方法对数组中的每个元素执行一个自定义reducer函数(升序执行),将其结果汇总为单个返回值

const array = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

const a = array.reduce(reducer);   // 1 + 2 + 3 + 4
console.log(a);   // 10

const b = array.reduce(reducer, 5);   // 5 + 1 + 2 + 3 + 4
console.log(b);   // 15

reducer 函数接收 4 个参数:

  1. Accumulator (acc) (累计器)
  2. Current Value (cur) (当前值)
  3. Current Index (idx) (当前索引)
  4. Source Array (src) (源数组)

您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值


语法

arr.reduce(callback(acc, cur, idx, src), initialValue)

参数:

callback

  • accumulator 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)
  • currentValue 数组中正在处理的元素
  • index (可选) 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始
  • array (可选) 调用reduce()的数组

initialValue (可选)

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

函数累计处理的结果


应用

计算数组里所有值的和
var sum = [0,1,2,3].reduce(
  (acc, cur)=> acc + cur,
  0
)

console.log(sum)
累加对象数组里的值
const arr = [{x: 1}, {x: 2}, {x: 3}]
let sum = arr.reduce(
  (acc, cur)=> acc + cur.x,
  0
)

console.log(sum)
二维数组转化为一维数组
const arr = [[0, 1], [2, 3], [4, 5]]
let change = arr.reduce(
  (acc, cur)=> acc.concat(cur),
  []
)

console.log(change)
计算数组中每个元素出现的次数
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let count = names.reduce(
  (allnames, name)=> {
    if(name in allnames) {
      allnames[name]++
    }else {
      allnames[name] = 1
    }
    return allnames
  },
  {}
)

console.log(count)
// console

[object Object] {
  Alice: 2,
  Bob: 1,
  Bruce: 1,
  Tiff: 1
}
按属性 object 分类
const people = [
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];

let groupBy = (all, select)=> {
  return all.reduce(
    (acc, obj)=> {
      let key = obj[select]
      if(!acc[key]) {
        acc[key] = []
      }
      acc[key].push(obj)
      return acc
    }, {}
  )
}

let groupedPeople = groupBy(people, 'age')

console.log(groupedPeople)
// console

{ 
  20: [
    { name: 'Max', age: 20 }, 
    { name: 'Jane', age: 20 }
    ], 
  21: [
    { name: 'Alice', age: 21 }
  ] 
}
使用扩展运算符和initialValue绑定包含在对象数组中的数组
const 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
}];


let allbooks = friends.reduce(
  (acc, cur)=> [...acc, ...cur.books], 
  []
);

console.log(allbooks);
// console

["Bible", "Harry Potter", "War and peace", "Romeo and Juliet", "The Lord of the Rings", "The Shining"]
数组去重
const arr = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd'];

let newArr = arr.reduce(
  (acc, cur)=> {
    if(acc.indexOf(cur) === -1) {
      acc.push(cur)
    }
    return acc
  }, []
)

console.log(newArr)   // ["a", "b", "c", "e", "d"]
// 同上方法,判断 acc 数组里有没有 cur ,没有就往里加

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];

let newArr = arr.sort().reduce(
  (acc, cur)=> {
    if(acc.indexOf(cur) === -1) {
      acc.push(cur)
    }
    return acc
  }, []
)

console.log(newArr)   // [1, 2, 3, 4, 5]


// 判断 acc 初始值为空,或者 acc 最后的值不为 cur (arr数组中最后一项)

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];

let result = arr.sort().reduce((init, current) => {
    if(init.length === 0 || init[init.length-1] !== current) {
        init.push(current);
    }
    return init;
}, []);

console.log(result);   // [1,2,3,4,5]
按顺序运行 Promise
let runPromiseInSequence = (arr, input) => arr.reduce(
  (promiseChain, currentFun) => promiseChain.then(currentFun),
  Promise.resolve(input)
)

let p1 = (a) => (new Promise((res, rej)=> {
  res(a*5)
}))

let p2 = (a) => (new Promise((res, rej)=> {
  res(a*2)
}))

let f3 = (a) => a * 3

let f4 = (a) => a * 4

const promiseArr = [p1, p2, f3, f4]

runPromiseInSequence(promiseArr, 10)
  .then(console.log)   // 1200
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值