BFE.dev前端刷題2 - 實現curry() 並支持placeholder

https://bfe.dev 是一個針對前端的刷題網站,像是前端的LeetCode。

該系列文章是我在上面的刷題日記。前端

題目 2

Alt Text

實現curry() 並支持placeholder. implement curry() with placeholder supportapp

分析 & 代碼

和第一問 #1. implement curry() 不一樣的地方就是對於placeholder的處理,咱們先看看examplefrontend

curriedJoin(1, 2, 3) // '1_2_3'
curriedJoin(_, 2)(1, 3) // '1_2_3'
curriedJoin(_, _, _)(1)(_, 3)(2) // '1_2_3'

也就是說,後來的參數須要放置在以前的placeholder的地方。
大概想法和第一問是同樣的,除了在判斷參數是否夠用的時候,須要過濾掉placeholder. 像這樣:網站

const expectedArgLength = func.length
const isArgsEnough = args.length >= expectedArgLength &&
  args.slice(0, expectedArgLength)
    .every(arg => arg !== curry.placeholder)
    
if (isArgsEnough) {
  return func.apply(this, args)
} else {
  // TODO
}

若是參數不夠,和以前同樣咱們須要把參數和後來調用的參數合併在一塊兒,再遞歸。
可是 Function.prototype.bind 只能簡單地按先後順序concat,因此這裏咱們不用bind,而是本身尋找placeholder而後merge。this

if (isArgsEnough) {
  return func.apply(this, args)
} else {
  return function(...newArgs) {
    // we need merge two arg list,  newArgs and args
    const finalArgs = []
    let i = 0
    let j = 0
    while (i < args.length && j < newArgs.length) {
      if (args[i] === curry.placeholder) {
        finalArgs.push(newArgs[j])
        i += 1
        j += 1
      } else {
        finalArgs.push(args[i])
        i += 1
      }
    }

    while (i < args.length) {
      finalArgs.push(args[i])
      i += 1
    }

    while (j < newArgs.length) {
      finalArgs.push(newArgs[j])
      j += 1
    }
     
    // then just call the curried function again
    return curried(...finalArgs)
  }
}

nice,經過了!spa

Alt Text

最後

第二問比第一問 BFE.dev#1. implement curry() 要難一些。有興趣的話你也能夠挑戰一下。prototype

感謝閱讀,但願能有些幫助,下次見。3d

相關文章
相關標籤/搜索