Submission link - https://bigfrontend.dev/problem/implement-curry-with-placeholder/discuss/769
/**
* @param { Function } func
*/
function curry(func) {
return function curried(...args) { // we need to return a function to make it curry-able.
const sanitizedArgs = args.slice(0, func.length);
const hasPlaceholder = sanitizedArgs.some(arg => arg == curry.placeholder);
if(!hasPlaceholder && sanitizedArgs.length == func.length) {
return func.apply(this, sanitizedArgs);
}
return function next(...nextArgs) {
return curried.apply(this, mergeArgs(sanitizedArgs, nextArgs));
}
}
}
function mergeArgs(args, nextArgs) {
let result = [];
args.forEach((arg, idx) => {
if(arg == curry.placeholder) {
result.push(nextArgs.shift());
} else {
result.push(arg);
}
});
return [...result, ...nextArgs];
}
curry.placeholder = Symbol()
This is an extended version of problem 1. Implement curry() where we need to replace placeholder value with the next argument values. After 1.5 days of struggle and peeking at few a solutions, here I am presenting you with an explanation.
Part 1 -
- We create a function called
curried
that we return to take arguments - We sanitize arguments to remove extra arguments (possible due to placeholders)
- We check if sanitized arguments
sanitizedArgs
>= functionfunc
parameters or not - We also check if any placeholder is present in the given arguments
- If the above both the conditions are
true
then we callfunc
with all arguments we received (normal currying case)
Part 2 -
- Else we will merge
args
andnextArgs
to replace placeholders with actual available arguments - We will iterate over
args
and push the first element ofnextArgs
(also remove it fromnextArgs
) if we find a placeholder element inargs
- Once the loop is over, we will merge the replaced arguments with the remaining
nextArgs
Part 1 -
- To make a function curry-able, we return a function
curried
- The
curried
will take argumentsargs
- We will sanitize (remove placeholders)
args
to count the length of the arguments - We will also check if these arguments have the placeholder
- We will check if
sanitizedArgs.length
(sanitize arguments) ==func.length
(total parameters) and there is no placeholder in the arguments- If both the above conditions are
true
then we directly callfunc
withsanitizedArgs
arguments - Else we will return another function
next
(because few arguments are still pending) to collect the next arguments
- If both the above conditions are
- The
next
function will call thecurried
function which will -- Take
sanitizedArgs
arguments andnextArgs
and merge them to replace placeholders with next arguments
- Take
- We will call the
curried
function with merged arguments
Part 2 - mergeArgs
- We will create a
result
array to add valid and replaced arguments - We will iterate over
args
and keep adding the first element fromnextArgs
if the current argumentarg
fromargs
contains the placeholder - When we add the first element from
nextArgs
then we remove that element from it too.nextArgs.shift()
- If there is no placeholder then we will push
arg
in theresult
array - Once the loop is completed, we will merge the
result
and the remainingnextArgs
.- This is a case where
nextArgs
>args
- This is a case where
- We will return merged arguments
result
That's it.
I'm excited to improve the solution and code walkthrough. Feel free to drop a comment, or send a PR or send memes @knowkalpesh.