reduce用法

53 阅读1分钟

callbackFn里面有4个参数,

  • accumulator: 上一次调用callbackFn的结果,在第一次调用时候,如果指定流initialValue,则为指定的值,否则为array[0]
  • currentValue: 在第一次调用时候,如果指定流initialValue,则为array[0],否则array[1]
  • currentIndex: 在数组中的索引位置,在第一次调用时,如果指定了initialValue,则为0,否则为1
  • array:调用了reduce数组本身

1、如果没有initialValue,reduce会从索引1开始执行回调,跳过第一个索引

2、对空数组调用reduce且不提供初始值会抛出TypeError

3、reduce不会改变原数组,而是返回一个新值

// 求和
const a1 = [1,2,3,4,5,6];
const result1 = a1.reduce((acc, cur) => acc+cur, 0);
console.log('result1', result1);

// 数组扁平化
const a2 = [[1,2,3], [4,5,6]]
const result2 = a2.reduce((acc, cur) => acc.concat(cur), [])
console.log('result2', result2)

// 找出最大值
const a3 = [1,2,3];
const r3 = a3.reduce((acc, cur) => Math.max(acc, cur), -Infinity);
console.log('r3', r3)

// 统计元素出现次数
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const r4 = fruits.reduce((acc, cur) => {
  acc[cur] = (acc[cur] || 0) +1;
  return acc;
}, {})
console.log('r4', r4)

// 按属性分组对象数组
const people = [
  {name: 'Alice', age: 21},
  {name: 'Bob', age: 20},
  {name: 'Charlie', age: 21}
];

const r5 = people.reduce((acc, cur) => {
  const key = cur.age;
  if(!acc[key]) {
    acc[key] = []
  }
  acc[key].push(cur);
  return acc;
}, {})

console.log('r5', r5);

//链式调用
//伪代码
const promises = [promise1, promise2, promise3];

const r6 = promises.reduce((acc, cur) => {
  return acc.then(cur)
}, Promise.resolve());
console.log('r6', r6)

自定义一个reduce

//自定义一个reduce

function myReduce(array, fn, initialValue) {
  if(typeof fn !== 'function') {
    throw new TypeError('必须是个function')
  }
  if(array.lenght === 0 && initialValue === undefined) {
    throw new TypeError('数组为空且没有初始值')
  }

  let startIndex;
  let acc;

  if(initialValue !== undefined) {
    acc = initialValue;
    startIndex = 0;
  } else {
    acc = array[0];
    startIndex = 1;
  }

  for(let i = startIndex; i< array.length; i++) {
    acc = fn(acc, array[i], i, array)
  }

  return acc;
}