https://bfe.dev/ja はFrontEnd版のLeetCode、GAFAの面接を受けるなら練習した方がいいかなと。
以下は自分の練習記録です。
第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)
}
}
よし、通った!
BFE.dev#1. curry()を実装するよりこの問題は難しい。
役に立てると嬉しいです! 次回を楽しみに!