Array.prototype.reduce使用技巧

先看一下规范对这个方法的几个说明:

Array.prototype.reduce ( callbackfn [ , initialValue ] )

NOTE 1:callbackfn should be a function that takes four arguments. reduce calls the callback, as a function, once for each element present in the array, in ascending order.

callbackfn is called with four arguments: the previousValue (value from the previous call tocallbackfn), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time that callback is called, the previousValue and currentValue can be one of two values. If an initialValue was provided in the call to reduce, then previousValuewill be equal to initialValue and currentValue will be equal to the first value in the array. If noinitialValue was provided, then previousValue will be equal to the first value in the array andcurrentValue will be equal to the second. It is a TypeError if the array contains no elements and initialValue is not provided.

reduce does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by reduce is set before the first call to callbackfn. Elements that are appended to the array after the call to reduce begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time reduce visits them; elements that are deleted after the call to reduce begins and before being visited are not visited.

The length property of the reduce method is 1.

NOTE 2:The reduce function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

 

使用示例:

1:累加,累乘

[1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array) {
  return accumulator * currentValue;
});

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

2:嵌套数组扁平化

let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  ( accumulator, currentValue ) => accumulator.concat(currentValue),
  []
);

3:对数组分组进行统计

let people = [
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];

function groupBy(objectArray, property) {
  return objectArray.reduce((acc, obj) => {
    let key = obj[property];
    (acc[key] || (acc[key] = [])).push(obj)
    return acc;
  }, {});
}

let groupedPeople = groupBy(people, 'age');
// { 
//   20: [
//     { name: 'Max', age: 20 }, 
//     { name: 'Jane', age: 20 }
//   ], 
//   21: [{ name: 'Alice', age: 21 }] 
// }

4:数组元素去重

let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd'];
let myOrderedArray = myArray.reduce((accumulator, currentValue) => {
  if (accumulator.indexOf(currentValue) === -1) {
    accumulator.push(currentValue);
  }
  return accumulator
}, [])

console.log(myOrderedArray);
//使用new Set能够更简单的实现上述功能

5:Promise顺序化

function runPromiseInSequence(arr, input) {
  return arr.reduce(
    (promiseChain, currentFunction) => promiseChain.then(currentFunction),
    Promise.resolve(input)
  );
}

function p1(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 5);
  });
}

function p2(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 2);
  });
}

function f3(a) {
 return a * 3;
}

function p4(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 4);
  });
}

const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10).then(console.log);   // 1200
//在进行上传文件的时候,为了防止后台服务压力过大,可以在前端把用户多选的文件实现顺序上传
//并且接收返回的结果

requestSerial: requests => requests.reduce((promise, request) => 
		promise.then(result => request().then(Array.prototype.concat.bind(result))), Promise.resolve([]))

//传入的参数是个请求函数数组,例如
req1() => {
    return $.ajax()
}

req2() => {
    return $.ajax()
}

requestSerial([req1, req2]).then(results => {
})

5:函数管道化

/ Building-blocks to use for composition
const double = x => x + x;
const triple = x => 3 * x;
const quadruple = x => 4 * x;

// Function composition enabling pipe functionality
const pipe = (...functions) => input => functions.reduce(
    (acc, fn) => fn(acc),
    input
);

// Composed functions for multiplication of specific values
const multiply6 = pipe(double, triple);
const multiply9 = pipe(triple, triple);
const multiply16 = pipe(quadruple, quadruple);
const multiply24 = pipe(double, triple, quadruple);

// Usage
multiply6(6); // 36
multiply9(9); // 81
multiply16(16); // 256
multiply24(10); // 240

6:Array-like 对象同样可以适用于reduce,无特殊要求,例如arguments对象

 

本文主要参考:

https://www.ecma-international.org/ecma-262/6.0/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值