我想用Javascript编写一个函数,它允许我传入一个数学运算符和一个it列表,并对该列表中的每一项应用运算符。
从总和的角度来看,这是我得出的结论:
function accumulate(list, operator){
var sum = 0;
for each(var item in list){
sum = accumulator(sum, item);
}
print(sum);
}
测试此代码会产生以下错误:
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.
发布于 2014-03-10 23:04:20
如果您计划执行的所有操作都是二进制操作,那么您可以这样做
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
发布于 2014-03-10 23:46:45
我认为你可以用几种不同的方法来做到这一点,但我建议你这样做:
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, '*'));
在上面的例子中,你只需要像accumul([2, 3, 4], 0, '+');
这样的东西来调用你的函数。operatorFunction[operator]
调用相应的操作符函数。
使用node.js在命令行中运行该示例,结果如下:
$ node accumulate.js
9
-9
24
0
1
如果数组为空,则此版本也可用。如果列表为空,则不能使用list.reduce
。
发布于 2018-07-31 08:45:45
我知道这是一个老问题。只是添加一些更多的信息。
如果您经常使用运算符,并且需要对结果进行reduce
(accumulate
),强烈建议您开发不同的helper,以便您可以使用任意输入表单快速获取结果。
尽管在使用reduce
时并不总是这样,但下面的帮助器将允许将数组的第一个元素作为default
值传递:
reducer = (list, func) => list.slice(1).reduce(func, list.slice(0, 1).pop())
以上代码仍然具有function
依赖项,因此您仍然需要声明包装目标operator
的特定函数
sum = list => reducer(list, (a, b) => a + b)
sum([1, 2, 3, 4, 5])
然后,您可以重新定义sum
,例如,您看到的新输入格式将是向后兼容的。在这个示例中,使用了一个新的助手flat
(现在仍处于实验阶段;添加了代码):
flat = (e) => Array.isArray(e) ? [].concat.apply([], e.map(flat)) : e
sum = (...list) => reducer(flat(list), (a, b) => a + b)
mult = (...list) => reducer(flat(list), (a, b) => a * b)
sum([1, 2, 3, 4, 5])
sum(1, 2, 3, 4, 5)
mult([1, 2, 3, 4, 5])
mult(1, 2, 3, 4, 5)
然后,您也可以使用reducer
(或您认为更有用的任何变体)来简化其他helper的定义。最后一个矩阵自定义运算符的例子(在本例中,它们是functions
):
zip = (...lists) => lists[0].map((_l, i) => lists.map(list => list[i]))
dot_product = (a, b) => sum(zip(a, b).map(x => mult(x)))
mx_transpose = (mx) => zip.apply([], mx)
// the operator
mx_product = (m1, m2) =>
m1.map(row => mx_transpose(m2).map(
col => dot_product(row, col) ))
// the reducer
mx_multiply = (...mxs) => reducer(mxs, (done, mx) => mx_product(done, mx))
A = [[2, 3, 4],
[1, 0, 0]]
B = [[0, 1000],
[1, 100],
[0, 10]]
C = [[2, 0],
[0, 0.1]]
JSON.stringify(AB = mx_product (A, B))
JSON.stringify(ABC = mx_product (AB, C))
JSON.stringify(ABC2 = mx_multiply(A, B, C))
https://stackoverflow.com/questions/22303738
复制相似问题