reduce比你想象中更強大

前言

前面的這篇文章 JS 基礎! | 扁平數(shù)組和JSON樹的轉換 利用到了 reduce來實現(xiàn)數(shù)組轉為map,以及結合concat實現(xiàn)數(shù)組遞歸拼接。今天我們來看看還能搞些什么名堂~

簡單復習一下 reduce

語法

let value = arr.reduce(function(previousValue, item, index, array) {
  // ...
}, [initial]);

參數(shù):

  • previousValue: 上一個函數(shù)調用的結果,第一次等于 initial(如果提供了 initial的話)。
  • item: 當前的數(shù)組元素。
  • index:當前索引。
  • arr: 數(shù)組本身。

previousValue實際上有點像累加,所以一些地方也會叫將這個參數(shù)稱為accumulator,存儲前面所有的執(zhí)行結果,最后會成為reduce的結果。


可讀性

但通常,你一般是不會完全參照這些參數(shù)定義的意思來決定參數(shù)名稱,而是要看具體開發(fā)遇到的場景來給其取可讀性高的名稱。

部分應用

1. 經典累加器

將數(shù)組中的值從左到右累加,大家學reduce的時候第一個例子應該就是這個。這里只是簡單的提一下,不是本文的重點~

const a = [1, 2, 8, 7, 4];

const sum = a.reduce((pre, cur) => {
    const res = pre + cur;
    return res;
}, 0);

console.log(sum); // 22

2. 二維數(shù)組轉一維

結合 concat實現(xiàn)數(shù)組扁平化

const arr2 = [
    [1, 2],
    [3, 4],
    [5, 6],
].reduce((acc, cur) => {
    return acc.concat(cur);
}, []);

console.log(arr2); //

3. 多維數(shù)組扁平

這個算是上一個的進階和更為通用的版本~
這篇文章里就用到了類似的,結合 concat 和遞歸

const arr3 = [
    [1, 2],
    [3, 4],
    [5, [7, [9, 10], 8], 6],
];
const flatten = arr =>
    arr.reduce(
        (pre, cur) => pre.concat(Array.isArray(cur) ? flatten(cur) : cur),
        []
    );
console.log(flatten(arr3)); // [ 1, 2, 3, 4, 5, 7, 9, 10, 8, 6 ]

4. 數(shù)組分塊

根據(jù)傳入限制大小,對數(shù)組進行分塊。
小于限制長度時就往里添加,否則直接將其加入res

const chunk = (arr, size) => {
    return arr.reduce(
        (res, cur) => (
            res[res.length - 1].length < size
                ? res[res.length - 1].push(cur)
                : res.push([cur]),
            res
        ),
        [[]]
    );
};
const arr4 = [1, 2, 3, 4, 5, 6];
console.log(chunk(arr4, 3)); // [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]

5. 字符統(tǒng)計

統(tǒng)計文本中各個字的數(shù)量

const countChar = text => {
    text = text.split("");
    return text.reduce((record, c) => {
        record[c] = (record[c] || 0) + 1;
        return record;
    }, {});
};
const text = "劃水水摸魚魚";
console.log(countChar(text)); // { '劃': 1, '水': 2, '摸': 1, '魚': 2 }

思考

本文只講了幾個應用,其實還有更多的應用,以及一些實現(xiàn) JS API 的功能,比如

  • 數(shù)組填充
  • 求最大、最小值
  • reverse
  • map
  • ...

等等,這些代碼段的整合網上已經有夠多了,我這里想總結一下寫出這些實用、通用的代碼需要進行怎樣的思考

core-js

其實從 Polyfill ofArray.prototype.reduceincore-js 中可以從另一個角度理解 reduce 中第一個參數(shù)回調函數(shù)中接收的第一個參數(shù):

class Array {
  //...
  reduce(callbackfn: (memo: any, value: any, index: number, target: any) => any, initialValue?: any): any;
 //...
}

他這里用的是 memo,中文直接翻譯過來就是備忘錄,在計算機中我們或許更為喜歡用緩存。我個人認為是更為符合我們寫出好用的代碼片段的。
他的精髓所在正是將回調函數(shù)作用于數(shù)組中的各個成員上,而上一次return的值就作為memo,傳入到下一個之中,你可以在這里面逐一處理:

  • 不斷更新迭代(累加)
  • 將結果拼接(扁平化)
  • 將特定的值添加到同一個對象之中(字符統(tǒng)計)

最后作為想要得到最終效果展現(xiàn)出來~

總結

image.png

寫代碼,大概是這么幾個節(jié)點

  1. 了解語法
    1. 傳參
    2. 返回
  2. 真正領悟到語言的特性,并能將其運用到實際開發(fā)中,寫出更好更簡潔更實用的代碼
  3. 多看:要從從這些代碼段中以及網上各路好漢寫的實用代碼學習怎么樣真正地像寫詩一樣寫代碼~
  4. 多寫
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容