重新學習Array.reduce()

最近在項目裏摳語言包的過程中發現做了很多重複的工作,然後同事指點了一下reduce這個方法,彷彿打開了新世界的大門。遂重新學習了一下reduce的用法。在博客記錄一下。

提示:努力想把文章寫的精簡,但是覺得關於這個函數很多細節想寫。所以這篇觀感可能會是: 博主是個bb怪。 

測試:

如果你能理解下列函數的原理,那麼這篇文章你完全沒有閱讀必要。

// 版本1
[...new Array(100).values()].map((item, index) => index + 2).reduce((a, b) => `${a} MINE_${b}: "", \n`, 'MINE_1: "",');

// 另一種寫法
[...new Array(100).toString().split(',').keys()].reduce((a, b) => `${a} MINE_${b}: "", \n`,'');

一、定義 

array.reduce( function(accumulator,  currentValue,  currentIndex,  array), initialValue ); 

accumulator:上一次調用回調返回的值,或者是提供的初始值(initialValue)

currentValue:數組中正在處理的元素

currentIndex:數據中正在處理的元素索引,如果提供了 initialValue ,從0開始;否則從1開始。【可選】

array: 調用 reduce 的數組【可選】

initialValue:可選項,其值用於第一次調用 callback 的第一個參數。如果沒有設置初始值,則將數組中的第一個元素作爲初始值。【可選】這裏注意如果對一個空數組使用 [ ].reduce 方法會報錯。原因看下面例子。

array.reduce 的返回值是這個函數累計處理的結果。

// 用代碼解釋定義
let demo = [ 333, 222, 111 ];

//沒有定義initialValue
demo.reduce((acc, curVal) => { console.log(acc) })  
// 輸出: 333, undefined, undefined 

//定義initialValue爲1
demo.reduce((acc, curVal) => { console.log(acc)}, 1)
// 輸出: 1, undefined, undefined 

//空數組不定義initialValue
[].reduce((a,b) => console.log(a))
// 輸出:Uncaught TypeError: Reduce of empty array with no initial value
// 因爲沒有定義初始值,a會默認取數組第一個值,而空數組,第一個值是undefined,所以報錯。

/* 說明:回調函數第一次執行時,accumulator 和currentValue的取值有兩種情況:如果調用reduce()時提供了initialValue,accumulator取值爲initialValue,currentValue取數組中的第一個值;如果沒有提供 initialValue,那麼accumulator取數組中的第一個值,currentValue取數組中的第二個值。輸出中有undefined 是因爲acc返回的是上一次函數返回的結果,但這裏我們函數僅是打印,沒有返回值,所以是undefined */

二、它可以方便的做一些事

數組求和

將數組轉化爲對象、計算數組中每個元素出現的次數、按屬性對數組分類

按順序運行promise

2.1 數組求和

let demo = [ { x: 1}, { x: 2 }, { x: 3} ],

demo.reduce((arr,val) => { return arr + val.x }, 0); 

// return: 6

2.2 數組轉化爲對象

let demo = [
  {
    id: 1,
    username: 'john',
    sex: 1,
    email: '[email protected]'
  },
  {
    id: 2,
    username: 'jerry',
    sex: 1,
    email: '[email protected]'
  },
  {
    id: 3,
    username: 'nancy',
    sex: 0,
    email: ''
  }
];

demo.reduce( (acc,val) => { return {...acc, [val.username]: val} } , {} )

2.3 按順序執行promise

/**
 * 直接抄官網的例子
 * Runs promises from array of functions that can return promises
 * in chained manner
 *
 * @param {array} arr - promise arr
 * @return {Object} promise object
 */
function runPromiseInSequence(arr, input) {
  return arr.reduce(
    (promiseChain, currentFunction) => promiseChain.then(currentFunction),
    Promise.resolve(input)
  );
}

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

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

// function 3  - will be wrapped in a resolved promise by .then()
function f3(a) {
 return a * 3;
}

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

const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10)
  .then(console.log);   // 1200

2.4 數組去重

reduce當然也能做到,但是我更喜歡下面這個方式

let demo = [ 1, 1, 2, 3];

//一行完成數組去重並升序排序
[...new Set(demo)].sort();

參考鏈接:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

https://www.jianshu.com/p/b415e46b4c8a

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章