關於Reduce的4種經常使用方法

reduce在咱們平常的開發中,使用的頻率並非很高,若是使用得當,相信你會在平常的工做中,更加的駕輕就熟。同時,部分公司的面試,有時也會去問到關於reduce的一些知識,這就讓咱們不得不防備(學習)了。javascript

定義

reduce() 方法接收一個函數做爲累加器,數組中的每一個值(從左到右)開始縮減,最終計算爲一個值。前端

語法

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])java

參數

callback : 執行數組中每一個值的函數,包含四個參數:面試

  • accumulator : 累計器累計回調的返回值;它是上一次調用回調時返回的累計值,或 initialValue(見下面)累計器
  • currentValue : 數組中正在處理的元素;當前值
  • currentIndex(可選) : 數組中正在處理的元素的索引;當前索引
  • array(可選) : 調用reduce()的數組;數組

initialValue (可選): 做爲第一次調用callback函數時的第一個參數的值。若是沒有提供初始值,則將使用數組中的第一個元素,在沒有初始值的空數組上調用reduce將報錯數組

返回值

函數累計處理的結果(accumulator)函數

解析

回調函數第一次執行時,accumulator 和currentValue的取值有兩種狀況:若是調用reduce()時提供了initialValue,accumulator取值爲initialValue,currentValue取數組中的第一個值;若是沒有提供 initialValue,那麼accumulator取數組中的第一個值,currentValue取數組中的第二個值。 平常的使用中,常常會忽略initialValue的存在,建議使用時添加initialValue參數,是其更加方便閱讀、理解學習

reduce()如何運行

[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
  return accumulator + currentValue;
});
複製代碼

callback 被調用四次,每次調用的參數和返回值以下表:ui

callback accumulator currentValue currentIndex array return value
second call 0 1 1 [0, 1, 2, 3, 4] 1
third call 1 2 2 [0, 1, 2, 3, 4] 3
fourth call 3 3 3 [0, 1, 2, 3, 4] 6

reduce返回的值將是最後一次回調返回的值(10)this

常見reduce使用

數組裏全部值的和

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15

複製代碼

累加對象數組裏的值

var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
},initialValue)

console.log(sum) // logs 6

複製代碼

將二維數組轉換爲一維

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  function(a, b) {
    return a.concat(b);
  },
  []
);
// flattened is [0, 1, 2, 3, 4, 5]

//箭頭函數
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
 ( acc, cur ) => acc.concat(cur),
 []
);

複製代碼

計算數組中每一個元素出現的次數

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

var countedNames = names.reduce(function (allNames, name) { 
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});

// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

複製代碼

數組去重

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current) => {
    if(init.length === 0 || init[init.length-1] !== current) {
        init.push(current);
    }
    return init;
}, []);
console.log(result); //[1,2,3,4,5]
複製代碼

翻譯mdn中的reduce

if (!Array.prototype.reduce) {
  Object.defineProperty(Array.prototype, 'reduce', {
    value: function(callback /*, initialValue*/) {
      if (this === null) {
        throw new TypeError( 'Array.prototype.reduce ' + 
          'called on null or undefined' );
      }
      if (typeof callback !== 'function') { // reduce的第一個參數必須爲函數
        throw new TypeError( callback +
          ' is not a function');
      }

      var o = Object(this);

      var len = o.length; 
      
      var k = 0; 
      var value;

      if (arguments.length >= 2) { //若是存在初始值,則存儲器的初始值爲initialValue
        value = arguments[1];
      } else {
        while (k < len && !(k in o)) {
          k++; 
        }
        if (k >= len) {  // 調用reduce的數組不能爲空
          throw new TypeError( 'Reduce of empty array ' +
            'with no initial value' );
        }
        value = o[k++];
      }

      while (k < len) {
      
        if (k in o) { //重複調用
          value = callback(value, o[k], k, o);
        }
        k++;
      }
      return value; //返回存儲器值
    }
  });
}
複製代碼

注意spa

  1. 若是數組爲空且沒有提供initialValue,會拋出TypeError
  2. 若是數組僅有一個元素(不管位置如何)而且沒有提供initialValue, 或者有提供initialValue可是數組爲空,那麼此惟一值將被返回而且callback不會被執行。

說到底,若是想更好的操做reduce(),仍是要必須掌握他的基本語法,callback函數的參數使用方式和initialValue; 感興趣的同窗,也能夠去查看關於reduce的源碼,相信你能夠收穫更多!


若是文章對的前端學習有幫助,別忘了點贊關注哦~

相關文章
相關標籤/搜索