BFE.devでのAI解答例 - JavaScript コーディング問題
2. placeholderをサポートするcurry()を実装する
解法:
前回の課題と同様に、curry()
関数を実装しますが、今回はplaceholder _
を解釈する必要があります。
まず、次のようにplaceholderのチェックユーティリティisPlaceholder()
を宣言します。
const isPlaceholder = x => x === '_' // placeholderはアンダースコア(_)
次に、curry()
関数内で、placeholderを扱うための新しい引数args
と配列params
を宣言します。 args
は関数に渡されるユーザー引数の配列であり、params
はplaceholderを含めたカリー化された関数の引数の配列です。placeholderがある場合、params
の対応する要素は「未定義」に設定されます。
const curry = func => { return function curried(...args) { const params = args.map(arg => isPlaceholder(arg) ? undefined : arg) if (params.includes(undefined)) { return (...remainingArgs) => { const newArgs = params.map(param => isPlaceholder(param) && remainingArgs.length ? remainingArgs.shift() : param) return curried(...newArgs.concat(remainingArgs)) } } else { return func(...params) } }}
次に、引数がplaceholder _
である場合を扱えるように、isPlaceholder()
関数を使用して新しい配列newArgs
に変換します。 newArgs
は、params
に初めから含まれている引数に加えて、残りの引数からの使用するplaceholderに対応する引数から構成されます。この関数はカリー化された関数を返し、placeholderが他に必要な場合は再帰的に呼び出されます。
最終的に、カリー化された関数が呼び出されたときにすべての引数が与えられた場合、元の関数が評価されます。
以下が完成したcurry()
関数のコードです。
const isPlaceholder = x => x === '_'const curry = func => { return function curried(...args) { const params = args.map(arg => isPlaceholder(arg) ? undefined : arg) if (params.includes(undefined)) { return (...remainingArgs) => { const newArgs = params.map(param => isPlaceholder(param) && remainingArgs.length ? remainingArgs.shift() : param) return curried(...newArgs.concat(remainingArgs)) } } else { return func(...params) } }}
これで、placeholder _
をサポートするcurry()
関数が完成しました。