2011-04-29 15 views
15

Necesito una función suma js para trabajar de esta manera:variadic curry función suma

sum(1)(2) = 3 
sum(1)(2)(3) = 6 
sum(1)(2)(3)(4) = 10 
etc. 

oí que no se puede hacer. Pero oí que si se puede agregar + al frente de sum se puede hacer. Me gusta +sum(1)(2)(3)(4).
¿Alguna idea de cómo hacer esto?

+0

Consulte también [aquí] (http://stackoverflow.com/a/18067040/1048572) para obtener más información – Bergi

+3

** Las funciones variables y el currying son incompatibles. ** ¡Simplemente no lo haga! La respuesta aceptada es un truco sucio. En su lugar, use funciones semi-variadas, donde los argumentos variados se pasan dentro de una matriz. – ftor

+0

Las funciones en JavaScript son variadas por defecto, por lo que piratear el lenguaje de esa manera es dañino, porque puede confundir a los novatos que recibir fns multirriesgos como este es el camino, aunque definitivamente no lo es. Hay formas más inteligentes de aprender cómo podemos usar el método 'valueOf'. –

Respuesta

48

No estoy seguro si he entendido lo que quiere, pero

function sum (n) { 
    var v = function (x) { 
     return sum (n + x); 
    }; 

    v.valueOf = v.toString = function() { 
     return n; 
    }; 

    return v; 
} 

console.log(+sum(1)(2)(3)(4)); 

JsFiddle

+0

esto se ve la parte, de hecho. aseado :) –

+0

Me alegra que podría ayudar :-) – Rafael

+2

Muy buena solución. Manera de leer realmente la pregunta, también. : P –

1

Puede hacer uso de la función de abajo

function add(num){ 
    add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0 
    add.sum += num; // increment it 
    return add.toString = add.valueOf = function(){ 
     var rtn = add.sum; // we save the value 
     return add.sum = 0, rtn // return it before we reset add.sum to 0 
    }, add; // return the function 
} 

Dado que las funciones son objetos, podemos añadir propiedades a ella, que estamos restableciendo cuando se ha accedido.

+0

Eso es genial, Amit! ¡Me gusta! –

+0

@YaroslavYakovlev ¡oh! Gracias :) –

+0

no has explicado lo que has escrito ... -1 –

1

Para que sum(1) se pueda llamar como sum(1)(2), debe devolver una función.

La función se puede llamar o convertir a un número con valueOf.

function sum(a) { 

    var sum = a; 
    function f(b) { 
     sum += b; 
     return f; 
    } 
    f.toString = function() { return sum } 
    return f 
} 
5

Este es un ejemplo del uso de corchetes vacíos en la última llamada como una clave cerca (de mi última entrevista):

sum (1) (4) (66) (35) (3)()

 function sum(numberOne) { 
     var count = numberOne; 
     return function by(numberTwo) { 
      if (numberTwo === undefined) { 
      return count; 
      } else { 
      count += numberTwo; 
      return by; 
      } 
     } 
    } 
    console.log(sum(1)(4)(66)(35)(3)()); 
4

les dejo esta revisión como su propio puesto ya que al parecer no tengo la reputación suficiente todavía para dejar sólo como un comentario. Esta es una revisión de la excelente solución de @Rafael.

function sum (n) { 
    var v = x => sum (n + x); 
    v.valueOf =() => n; 
    return v; 
} 

console.log(+sum(1)(2)(3)(4)); //10 

No encontré un motivo para mantener el bit v.toString, ya que no parecía necesario. Si cometí un error al hacerlo, hágamelo saber en los comentarios por qué se requiere v.toString (pasó mis exámenes sin él). Convirtió el resto de las funciones anónimas en funciones de flecha para facilitar la lectura.

+0

' toString' significa que 'console.log (" El resultado es "+ suma (1) +"! ")' funciona correctamente – Eric

+1

'console.log ("El resultado es" + suma (1) + "!") 'Devuelve la cadena' El resultado es 1! 'Incluso cuando el' toString' se omite de la declaración 'v.valueOf' en la función' sum' como lo he hecho anteriormente. Todavía no está claro qué agregar 'toString' lograría que eso no ocurra. – Brad

0

Dado que esta es una pregunta de la entrevista común, aquí es mi opinión utilizando las propiedades de función para agregar memoization a la función suma() y simplificar su código un poco:

function sum(x) { 
 
    sum.result = (sum.result) ? sum.result += x : x; 
 
    sum.valueOf = function() { 
 
    return sum.result; 
 
    } 
 
    return sum; 
 
} 
 

 
sum(1)(2)(3); // == 6

0

Aquí es una solución que utiliza ES6 y toString, similar a @Vemba

function add(a) { 
 
    let curry = (b) => { 
 
    a += b 
 
    return curry 
 
    } 
 
    curry.toString =() => a 
 
    return curry 
 
} 
 

 
console.log(add(1)) 
 
console.log(add(1)(2)) 
 
console.log(add(1)(2)(3)) 
 
console.log(add(1)(2)(3)(4))

Cuestiones relacionadas