Passer un opérateur mathématique en tant que paramètre

Je voudrais écrire une fonction en Javascript qui me permet de passer dans un opérateur mathématique et une liste d'ints et pour chaque élément de cette liste, lui appliquer l'opérateur.

En ce qui concerne une somme, c'est ce que j'ai trouvé:

function accumulate(list, operator){ var sum = 0; for each(var item in list){ sum = accumulator(sum, item); } print(sum); } 

Le test de ce code produit l'erreur suivante:

 var list = new Array(); list[0] = 1; list[1] = 2; list[2] = 3; 
 js> accumulate(list, +); js: "<stdin>", line 9: syntax error js: accumulate(list, +); js: ..................^ js: "<stdin>", line 9: Compilation produced 1 syntax errors. 

Vous ne pouvez pas passer un opérateur en tant que paramètre, mais vous pouvez passer une fonction:

 function accumulate(list, accumulator){ // renamed parameter var sum = 0; for(var i = 0; i < list.length; i++){ // removed deprecated for…each loop sum = accumulator(sum, list[i]); } print(sum); } accumulate(list, function(a, b) { return a + b; }); 

C'est très proche de ce que fait la fonction Array.prototype.reduce , mais pas exactement. Pour imiter le comportement de reduce , vous devriez obtenir le premier élément de la list et l'utiliser comme graine pour votre accumulateur, plutôt que d'utiliser toujours 0:

 function accumulate(list, accumulator, seed){ var i = 0, len = list.length; var acc = arguments.length > 2 ? seed : list[i++]; for(; i < len; i++){ acc = accumulator(acc, list[i]); } print(acc); } 

De cette façon, vous pouvez calculer le produit de la list (votre méthode renverra toujours 0):

 accumulate(list, function(a, b) { return a * b; }); 

Si toutes les opérations que vous envisagez de faire sont des opérations binaires, alors vous pouvez le faire

 var operations = { "+" : function (operand1, operand2) { return operand1 + operand2; }, "-" : function (operand1, operand2) { return operand1 - operand2; }, "*" : function (operand1, operand2) { return operand1 * operand2; } }; function accumulate(list, operator) { return list.reduce(operations[operator]); } console.log(accumulate([1, 2, 3, 4], "+")); // 10 console.log(accumulate([1, 2, 3, 4], "-")); // -8 console.log(accumulate([1, 2, 3, 4], "*")); // 24 

Je pense que vous pouvez le faire de plusieurs façons différentes, mais je vous suggère quelque chose comme ceci:

 var operatorFunction = { '+' : function(x, y) { return x + y; }, '-' : function(x, y) { return x - y; }, '*' : function(x, y) { return x * y; } }; function accumul(list, neutral, operator) { var sum = neutral; list.forEach(function(item) { sum = operatorFunction[operator](sum, item); }); return sum; } console.log(accumul([2, 3, 4], 0, '+')); console.log(accumul([2, 3, 4], 0, '-')); console.log(accumul([2, 3, 4], 1, '*')); console.log(accumul([], 0, '+')); console.log(accumul([], 1, '*')); 

Dans l'exemple ci-dessus, vous avez juste besoin de quelque chose comme accumul([2, 3, 4], 0, '+'); Pour vous appeler en fonction. operatorFunction[operator] appelle la fonction de l'opérateur correspondant.

Exécuter l'exemple dans la ligne de commande, avec node.js , donne:

 $ node accumulate.js 9 -9 24 0 1 

Cette version fonctionne également si le tableau est vide. Vous ne pouvez pas utiliser list.reduce si la liste est vide.

Malheureusement, il n'est pas vraiment possible de le faire comme vous essayez de le faire. Ce que je ferais, c'est passer un nombre, et avoir un if / then ou un switch / case pour décider quoi faire en fonction de ce numéro