柯里化reduce

實現reduce

reduce:累加器(accumulator)javascript

// 判斷非空
const isDef = function(o){
  return o !== undefined && o !== null
}

/** * fn 函數 * @param { * } total 初始值(計算結束後的返回值) * @param { * } currentValue 當前元素 * @param { Number } currentIndex 當前元素的索引 * @param { Array } arr 當前元素所屬的數組對象 */
 
// Array的prototype聲明$reduce
Array.prototype.$reduce = function(fn, tar){
  let len = this.length, // 目標數組長度
      res, // 數組
      i = 0; // 初始index
  if (isDef(tar)) {
    // 有第二個參數,total爲初始值
    res = tar
  } else {
    // 沒有第二個參數,初始值爲數組第一項
    res = this[0]
    // 因爲第一項爲初始值,就從第二項開始累計
    i++
  }
  // 循環數組
  while (i < len) {
    // 把算的值傳入fn第一個參數
    res = fn(res, this[i], i++, this)
  }
  return res
}
複製代碼

應用java

[1, 2, 3, 4, 5].$reduce((total, currentValue, currentIndex, arr) => {
  console.log(total, currentValue, currentIndex, arr)
  return total + currentValue;
}, 0) // => 15

// 0 1 0 [ 1, 2, 3, 4, 5 ]
// 1 2 1 [ 1, 2, 3, 4, 5 ]
// 3 3 2 [ 1, 2, 3, 4, 5 ]
// 6 4 3 [ 1, 2, 3, 4, 5 ]
// 10 5 4 [ 1, 2, 3, 4, 5 ]
複製代碼

函數式編程封裝(純函數)

返回一個函數,把this改成返回函數的參數(arr)git

// reduce : ((a, b) → a) → a → [b] → a
const reduce = function(fn, tar){
  const _isDef = function(o){
    return o !== undefined && o !== null
  }
  return function(arr){
    let len = arr.length,
        res,
        i = 0;
    if (_isDef(tar)) {
      res = tar
    } else {
      res = arr[0]
      i++
    }
    while (i < len) {
      res = fn(res, arr[i], i++, arr)
    }
    return res
  }
}
// 求和
const sum = reduce((a, b) => a + b, 0)
sum([1, 2, 3, 4, 5]) // 15

// 求乘積
const product = reduce((a, b) => a * b)
product([1, 2, 3, 4, 5]) // 120

// 求對象數組某元素的某一項和
const inSum = reduce((a, { score }) => a + score, 0)
inSum([{ score: 1 }, { score: 2 }, { score: 3 }]) // 6

複製代碼

ps. 函數式編程最好的參考書: legacy.gitbook.com/book/llh911…編程

相關文章
相關標籤/搜索