Home  >  Article  >  Web Front-end  >  A thorough understanding of the Array.reduce method in js in one article

A thorough understanding of the Array.reduce method in js in one article

藏色散人
藏色散人forward
2023-02-28 16:07:181963browse

This article brings you relevant knowledge about js. It mainly talks about the Array.reduce method in js. Friends who are interested can take a look at it together. I hope it will be helpful to everyone.

Preface

We often use the reduce method of the Array object to do some calculations or data combinations. We find that after using reduce for so many years, it is not I know it well and just recently discovered that it works fine if we don't pass the initial value, and the array can also be an array of functions to enhance our code.

This article will take you back to understand Array.reduce and application scenarios.

Re-understanding Array.reduce

Let’s take a look at how MDN describes it:

reduce() The method executes a reducer function provided by you in order for each element in the array. Each time the reducer is run, the calculation result of the previous element will be passed in as a parameter, and finally The results are summarized into a single return value.

Let’s take a look at this code:

const arr = [1, 2, 3]
const initValue = 10;
function reducer(previousValue, currentValue, currentIndex, arrryTarget) {
    return preValue + currentValue
}
arr.reduce(reducer, initValue) // res === 16

reduce will traverse the arr array. The reducer will be executed as many times as there are arrays. The parameters for each execution process (arrryTarget is the same, so it is meaningless, unless the original array is directly changed during the traversal process, so it is not considered here) are as follows:

returnFirst execution##Second execution112113The third execution133216 Anyone who has used reduce in this process should know that the original words on MDN are like this:
#reducer Repeated execution previousValue currentValue ##currentIndex
10 1 0 11

When the callback function is executed for the first time, there is no "last calculation result". If you need the callback function to start executing from the element with array index 0, you need to pass an initial value. Otherwise, the element with array index 0 will be used as the initial value
initialValue

, and the iterator will start executing from the second element (index 1 instead of 0)

That is When the reducer function is executed for the first time, there is no "last calculation result". The initial value is passed here, so the
reducer

function starts execution from the element with array index 0, that is, arr.length is equal to the reducer number of executions. But what if the initial value is not passed? Let's change the code:

const arr = [1, 2, 3]
- const initValue = 10;
function reducer(previousValue, currentValue, currentIndex, arrryTarget) {
    return preValue + currentValue
}
- arr.reduce(reducer, initValue) // res === 16
+ arr.reduce(reducer) // res === 6

At this time, the reducer will only execute

arr.length - 1

times. The parameters for each execution are as follows:

reducerpreviousValuecurrentValuecurrentIndex##First execution 3
Repeated execution return
1 ##2 1 3 Second execution
##3 2 6 <p>因为没有传递初始值,因此 <code>reducer 函数从数组索引为 1 的元素开始执行,首次执行的时候 arr[0] 被作为了 previousValuecurrentValue 为是 arr[1]

现在了 reduce 的基本用法,那么它的运用场景有哪些呢?

reduce 的运用场景

用于计算数据

因为 reducer 函数会重复执行 array.length 或者 array.length - 1,因此特别适合做一些计算。

比如累加,计算订单总金额等案例:

const orders = [{ id: 1, amount: 10 }, { id: 2, amount: 12 }, { id: 3, amount: 5 }]
const totalAmount = orders.reduce((sum, order) => sum + order.amount, 0); // 27

累加可以,那么 加减乘除 中其他三个的原理是一样的,这里不用多说,肯定是可以的,甚至加上 的计算也是可以的,比如

[true, true, false, true].reduce((a, b) => a & b); // 有false,按照与逻辑,一定会是false

将多维数组转为一维数组

reduce 可以很轻松的将二维数组转为一维数组。示例:

[[1,2], [3, 4]].reduce((arrA, arrB) => [...arrA, ...arrB])

那是不是封装一下就可以把多维数组组转为一维数组了?当然可以:

function flaten(arr) {
    if(!Array.isArray(arr)) {
        return arr;
    }
    return arr.reduce((result, item) => {
        // 不是数组,则直接放在数组末尾
        if(!Array.isArray(item)) {
            result.push(item);
            return result;
        }
        return result.concat(flaten(item))
    }, [])
}
flaten([1,2, [3, 4], [6, [7, 8]]]) // [1, 2, 3, 4, 6, 7, 8]

这样就很简单的实现一个深层次的 flaten 。

将函数作为参数

将函数作为参数的话,运用场景在哪里?比如:

[func1, func2. func3, func4].reduce((value, funcN) => funcN(value), value),

执行顺序: func1 => func2 => func3 => func4,

这个效果就和 pipe 很像了是不是?这样封装一下就可以让函数执行扁平化。而不是 func1(func2(func3(func4(value)))) 这样看着难受。有一篇详细的描述了将函数作为参数来实现 pipe 和 compose 函数的过程,有兴趣可以点击去看看

其他场景

MDN 其实还描述了很多使用场景,大家都可以去探索一下,总之 reduce 的功能很强大,俗称“万金油”不是没有道理的。

这里就简单列一下:

  • 计算数组中每个元素出现的次数(如果元素是对象,也可以计算某个值出现的次数)
  • 按属性对 object 分类
  • 使用扩展运算符和 initialValue 绑定包含在对象数组中的数组
  • 数组去重
  • 使用 .reduce() 替换 .filter() 或者 .map(),可以替换当然也可以实现。
  • 按顺序运行 Promise
  • .....

最后

js中其实有很多函数功能都很强大,这些函数的强大其实还是因为js本身的机制带来的,函数在js中是一等公民,注定会逐渐影响我们的编码风格,因此大家可以去了解和学习函数式编程,它能让你的代码写的更轻松。

推荐学习:《JavaScript视频教程

The above is the detailed content of A thorough understanding of the Array.reduce method in js in one article. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete