Heim >Web-Frontend >js-Tutorial >Ein umfassendes Verständnis der Array.reduce-Methode in js in einem Artikel

Ein umfassendes Verständnis der Array.reduce-Methode in js in einem Artikel

藏色散人
藏色散人nach vorne
2023-02-28 16:07:182060Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über js. Es geht hauptsächlich um die Array.reduce-Methode in js. Ich hoffe, dass es für alle hilfreich ist.

Vorwort

Wir verwenden oft die Reduce-Methode des Array-Objekts, um einige Berechnungen oder Datenkombinationen durchzuführen. Ich habe festgestellt, dass ich Reduce seit so vielen Jahren verwende, aber ich verstehe es erst seit kurzem Ich habe festgestellt, dass, wenn der Anfangswert nicht übergeben wird, dies auch normal erfolgen kann. Das Array kann auch ein Array von Funktionen sein, um unseren Code zu verbessern.

Dieser Artikel führt Sie zurück zum Verständnis von Array.reduce und Anwendungsszenarien.

Array.reduce noch einmal verstehen

Sehen wir uns an, wie MDN es beschreibt:

reduce() Die Methode führt eine Folge von Operationen für jedes Element im aus Array. Die von Ihnen bereitgestellte reduce()  方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

我们来看一下这段代码:

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

reduce 会遍历 arr 数组,数组有多少个,reducer 就会执行多少次。执行过程每一次的参数(arrryTarget都是一样的,因此没有意义,除非在遍历过程中直接改变了原数组,因此这里不考虑)如下:

reducer 重复执行 previousValue currentValue currentIndex return
第一次执行 10 1 0 11
第二次执行 11 2 1 13
第三次执行 13 3 2 16

这个过程用过 reduce 的应该都知道,MDN 上原话是这样的:

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)

也就是第一次执行 reducer 函数时,不存在“上一次的计算结果”。这里传递了初始值,因此 reducer 函数才从数组索引为 0 的元素开始执行,也就是 arr.length 等于 reducer 执行次数。

但如果不传递初始值呢?我们改动一下代码:

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

这时候 reducer 只会执行 arr.length - 1 次。执行过程每一次的参数如下:

Schauen wir uns diesen Code an:
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
reducer 重复执行 previousValue currentValue currentIndex return
第一次执行 1 2 1 3
第二次执行 3 3 2 6Reducer-Funktion übergibt bei jeder Ausführung die Berechnungsergebnisse der vorherigen Elemente als Parameter und fasst die Ergebnisse schließlich in einem einzigen Rückgabewert zusammen.
reduce durchläuft das arr-Array und der Reduzierer wird so oft ausgeführt, wie es Arrays gibt. Die Parameter jedes Ausführungsprozesses (arrryTarget ist derselbe und daher bedeutungslos, es sei denn, das ursprüngliche Array wird während des Durchlaufvorgangs direkt geändert und wird daher hier nicht berücksichtigt) lauten wie folgt: 🎜🎜
reducer Wiederholte Ausführung previousValue currentValue th> currentIndex return
Erste Ausführung🎜 10 🎜<td> <code>1🎜 0🎜 11🎜🎜
Zweite Ausführung🎜 11🎜 2🎜 1🎜 13🎜🎜 Die dritte Ausführung🎜 13🎜 3🎜 2🎜 16🎜🎜🎜🎜🎜Jeder, der reduzieren in diesem Prozess verwendet hat, sollte wissen, dass die ursprünglichen Wörter auf MDN wie folgt lauten: 🎜🎜🎜Wenn die Rückruffunktion zum ersten Mal ausgeführt wird, gibt es kein „letztes“. Berechnungsergebnis". Wenn Sie möchten, dass die Callback-Funktion ab dem Element mit Array-Index 0 ausgeführt wird, müssen Sie einen Anfangswert übergeben. Andernfalls wird das Element mit dem Array-Index 0 als Anfangswert initialValue verwendet und der Iterator beginnt mit der Ausführung ab dem zweiten Element (Index 1 statt 0)🎜🎜Das heißt, das erste Wenn die Reduzierfunktion zum ersten Mal ausgeführt wird, gibt es kein „letztes Berechnungsergebnis“. Der Anfangswert wird hier übergeben, sodass die Funktion reducer die Ausführung ab dem Element mit dem Array-Index 0 beginnt, d. h. arr.length entspricht der Anzahl der Ausführungen von reduzierer . 🎜🎜Was aber, wenn der Anfangswert nicht übergeben wird? Ändern wir den Code: 🎜
[true, true, false, true].reduce((a, b) => a & b); // 有false,按照与逻辑,一定会是false
🎜Zu diesem Zeitpunkt führt der Reduzierer nur arr.length - 1 Mal aus. Die Parameter für jeden Ausführungsprozess lauten wie folgt: 🎜🎜
reducer Wiederholte Ausführung previousValue currentValue currentIndex return
Erste Ausführung🎜 1🎜 2🎜 1🎜 3🎜🎜
Die zweite Ausführung🎜 3🎜 3🎜 2🎜 6🎜🎜🎜🎜

因为没有传递初始值,因此 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视频教程

Das obige ist der detaillierte Inhalt vonEin umfassendes Verständnis der Array.reduce-Methode in js in einem Artikel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen