函數(shù)柯里化與不定參數(shù)處理

題目一:函數(shù)式編程當(dāng)中有個非常重要的概念就是 函數(shù)柯里化,一個接受 任意多個參數(shù) 的函數(shù),如果執(zhí)行的時候傳入的參數(shù)不足,那么它會返回新的函數(shù),新的函數(shù)會接受剩余的參數(shù),直到所有參數(shù)都傳入才執(zhí)行操作。這種技術(shù)就叫柯里化,請你完成 curry 函數(shù),它可以把任意的函數(shù)進(jìn)行柯里化,效果如下:
const f = (a, b, c d) => { ... }
const curried = curry(f)
curried(a, b, c, d)
curried(a, b, c)(d)
curried(a)(b, c, d)
curried(a, b)(c, d)
curried(a)(b, c)(d)
curried(a)(b)(c, d)
curried(a, b)(c)(d)
// 這些函數(shù)執(zhí)行結(jié)果都一樣
例如:
const add = curry((a, b ,c ,d) => a + b + c +d)
add (1,2,3,4)=10
add(1)(2,3)(4)=10
add(1,2,3)(4)=10
add(1)(2)(3)(4)=10

題目二:不定參數(shù)處理
實(shí)現(xiàn)一個add方法,使計(jì)算結(jié)果能夠滿足如下預(yù)期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

答案
首先函數(shù)柯里化因?yàn)閰?shù)固定,使用vars數(shù)組保存每次傳進(jìn)來的參數(shù),然后判斷fn的參數(shù)個數(shù),如果fn參數(shù)個數(shù)正好等于vars數(shù)組中保存的個數(shù),那么執(zhí)行fn,否則遞歸一次,返回curried函數(shù),繼續(xù)等待輸入。這里外層curry 函數(shù)只會執(zhí)行一次便會被剝離,之后add會變成curried的一個引用,同時curried可以閉包引用外層的vars,使得每次傳入的參數(shù)可以長久保存。

      我的答案一:函數(shù)柯里化
        const curry = (fn,vars=[]) =>{
            const curried=(...args)=>{
                for(let i of [...args]){
                    vars.push(i)
                }
                if(vars.length==fn.length){
                    return fn(...vars)
                }else{
                    return curry(fn,vars)
                }
            }
            return curried
        }
網(wǎng)上更為優(yōu)秀的答案:用延展符將push做了簡化
const curry = (f, args1 = []) => (...args2) => {
  const args = [ ...args1, ...args2 ]
  return f.length === args.length
  ? f(...args)
  : curry(f, args)
}

參考上面網(wǎng)上優(yōu)秀答案的思路,寫出這個不定參數(shù)處理add函數(shù),...args可以接受不定參數(shù),由于題目二中并沒有題目一中const add = curry((a, b ,c ,d) => a + b + c +d)函數(shù)劫持的過程,所以不能直接返回函數(shù)定義,而是要返回一個執(zhí)行完的函數(shù)curried(...args),同時在curried中再返回一個函數(shù)定義curried,這樣就可以把函數(shù)連接起來了。由于參數(shù)不定,這里對每次傳入的參數(shù)都要進(jìn)行執(zhí)行處理,執(zhí)行方法是利用函數(shù)的隱式轉(zhuǎn)換,當(dāng)函數(shù)執(zhí)行結(jié)束時會有一個toString的操作,來使函數(shù)能參與其他的運(yùn)算,這里我們將toString從新定義,返回vars中的累加值,從而實(shí)現(xiàn)add運(yùn)算。

      我的答案二:不定參數(shù)處理
      const add=(...args)=>{
            let vars=[]
            const curried=(...c)=>{
                vars=[...vars,...c]
                return curried
            }
            curried.toString=()=>{
                 return vars.reduce((a,b)=>a+b,0)
            }
            return curried(...args)
        }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容