J'ai besoin d'une fonction js sum pour fonctionner comme ceci:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
J'ai entendu dire que ça ne pouvait pas être fait. Mais entendu que si l'ajout de +
devant sum
peut être fait . Comme +sum(1)(2)(3)(4)
.
Des idées sur la façon de faire cela?
Je ne sais pas si j'ai compris ce que vous voulez, mais
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));
Voici un exemple d'utilisation de crochets vides dans le dernier appel en tant que touche rapprochée (de ma dernière interview):
somme (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)());
Je publie cette révision comme sa propre publication, car je n'ai apparemment pas encore assez de réputation pour la laisser en commentaire. Ceci est une révision de l'excellente solution de @Rafael.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log(+sum(1)(2)(3)(4)); //10
Je n'ai vu aucune raison de conserver le bit v.toString, car cela ne semblait pas nécessaire. Si je me suis trompé, merci de me le faire savoir dans les commentaires, pourquoi v.toString est nécessaire Converti le reste des fonctions anonymes en fonctions de flèche pour faciliter la lecture.
Voici une solution utilisant ES6 et toString
, similaire à @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))
Vous pouvez utiliser la fonction ci-dessous
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
}
Les fonctions étant des objets, nous pouvons y ajouter des propriétés, que nous réinitialisons lorsqu’il a été consulté.
Voici une solution avec une fonction générique de curry variadic dans ES6 Javascript, avec l’avertissement qu’un final ()
est nécessaire pour invoquer les arguments:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
En voici un autre qui n'a pas besoin de ()
, en utilisant valueOf
comme dans la réponse de @ rafael . J'ai l'impression qu'utiliser valueOf
de cette manière (ou peut-être même du tout) est très déroutant pour les lecteurs de votre code, mais chacun pour leur propre compte.
La toString
dans cette réponse est inutile. En interne, lorsque javascript effectue une coersion de types, il appelle toujours valueOf()
avant d'appeler toString()
.
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
Une autre approche légèrement plus courte:
const sum = a => b => b? sum(a + b) : a;
Utilisable comme:
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Pour que sum(1)
soit appelable en tant que sum(1)(2)
, il doit renvoyer une fonction.
La fonction peut être appelée ou convertie en un nombre avec valueOf
.
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}