user10458813
user10458813

Reputation:

Javascript - Create a currying function returning the list of parameters

I'm trying to create a currying function returning the list of parameters but I don't how to make it. This is my code :

const getParameters = arg => {
  const parameters = [];

  const innerFunction = arg => {
    parameters.push(arg);
    return innerFunction;
  };
  return innerFunction(arg);
};

getParameters(1)(2)(5); // => expected value [1,2,5]
getParameters(1)(2)(5)(20); // => expected value [1,2,5,20]

Upvotes: 0

Views: 409

Answers (5)

Max
Max

Reputation: 2036

As we all know world of JavaScript is a magic world, and even this thing, like infinite currying is possible

const nice = (...args) => {
  return Object.assign(
    nice.bind(0, ...args), 
    { valueOf: () => args.reduce((a, b) => a + b, 0) }
  )
}

console.log(+nice(1)()(2)) // ~> 3
console.log(+nice(1, 2)()(3)()()) // ~> 6
console.log(+nice()()()()()()(1)) // ~> 1
console.log(+nice()()()(2)()()()) // ~> 2

console.log(nice(2)()(1) + '') // ~> '3'

console.log(nice()(3)() == 3) // ~> true

console.log(nice()(3)() === 3) // ~> false

The trick is that adding unary + or using non-strict equality calls valueOf method right after all function calls, so we've got ourselves an infinite currying :)

And list currying to answer your question. It works because '' + forces toString method to be called:

const nice = (...args) => {
  return Object.assign(
    nice.bind(0, ...args), 
    { toString: () => JSON.stringify(args) }
  )
}

console.log('' + nice(1,2)(3)(4)(5)(6,7)) // ~> [1,2,3,4,5,6,7]

By the way, it's possible to make this infinite currying even more legit, because it can take any type and any amount of parameters which is really cool.

Upvotes: 0

TheMaster
TheMaster

Reputation: 50654

If you can use a final parameter(like "x") to signify end, you can use .bind

const getParameters = function(...arg) {
  if (arg[arg.length - 1] !== 'x') {
    return getParameters.bind(null, ...arg);
  }
  arg.pop();
  return arg;
};
console.info(getParameters(1)(2)(5)('x'));
console.info(getParameters(1)(2)(5)(20)("x"))

Upvotes: 0

Vlad Levitskiy
Vlad Levitskiy

Reputation: 71

Not very good solution, but... Try this one if you want to have a string in output.

function getParameters(a) {

  let parameters = '[';
  parameters += `${a}`;

  function innerFunction(b) {
    parameters += `,${b}`;
    return innerFunction;
  }

  innerFunction.toString = function() {
    return `${parameters}]`;
  };

  return innerFunction;
}

console.log(getParameters(1)(3)(4)); //[1,3,4] 

Upvotes: 0

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

UPDATE: Support unlimited arguments. PS: only limitation is when you need to end the call, you have pass last call as null or undefined or empty as shown below.

const getParameters = a => {
  const parameters = [a];
  const innerFunction = b => {
    if (b) {
      parameters.push(b);
      return innerFunction;
    }
    return parameters;
  };
  return innerFunction;
};


console.log(getParameters(1)(2)(5)());
console.log(getParameters(1)(2)(5)(9)(20)(22)());

Upvotes: 0

Johnny Zabala
Johnny Zabala

Reputation: 2483

const getParameters = a => b => c => [a, b, c];

console.log(getParameters(1)(2)(5));

Upvotes: 1

Related Questions