LoginSignup
0
0

More than 3 years have passed since last update.

BFE.dev解答記録 #2. placeholderをサポートするcurry()を実装する

Last updated at Posted at 2020-09-23

https://bfe.dev/ja はFrontEnd版のLeetCode、GAFAの面接を受けるなら練習した方がいいかなと。
以下は自分の練習記録です。

Alt Text

第2問 BFE.dev#2. placeholderをサポートするcurry()を実装する

BFE.dev#1. curry()を実装するとちょっと違って、今度はplaceholderの対応が必要になる

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

実装方針は一緒、引数の数が足りるかどうかを確認する他、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
}

引数が足りない場合は、第1問と同じ引数を保存して次回の実行に渡す。

問題は、Function.prototype.bindは引数のリストを連結するだけで、欲しいのはplaceholderの入れ替えですね。

なのでこの場合は、bind()を使うのでなく、新しいfunctionを返して、古い引数と新しい引数をいい感じにmergeするように。

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)
  }
}

よし、通った!

Alt Text

BFE.dev#1. curry()を実装するよりこの問題は難しい。

役に立てると嬉しいです! 次回を楽しみに!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0