首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将数学运算符作为参数传递

将数学运算符作为参数传递
EN

Stack Overflow用户
提问于 2014-03-10 23:01:35
回答 7查看 27.9K关注 0票数 32

我想用Javascript编写一个函数,它允许我传入一个数学运算符和一个it列表,并对该列表中的每一项应用运算符。

从总和的角度来看,这是我得出的结论:

代码语言:javascript
复制
function accumulate(list, operator){
    var sum = 0;
    for each(var item in list){
        sum = accumulator(sum, item);
    }
    print(sum);
}

测试此代码会产生以下错误:

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

回答 7

Stack Overflow用户

发布于 2014-03-10 23:04:20

如果您计划执行的所有操作都是二进制操作,那么您可以这样做

代码语言:javascript
复制
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
票数 27
EN

Stack Overflow用户

发布于 2014-03-10 23:46:45

我认为你可以用几种不同的方法来做到这一点,但我建议你这样做:

代码语言:javascript
复制
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在命令行中运行该示例,结果如下:

代码语言:javascript
复制
$ node accumulate.js 
9
-9
24
0
1

如果数组为空,则此版本也可用。如果列表为空,则不能使用list.reduce

票数 7
EN

Stack Overflow用户

发布于 2018-07-31 08:45:45

我知道这是一个老问题。只是添加一些更多的信息。

如果您经常使用运算符,并且需要对结果进行reduce (accumulate),强烈建议您开发不同的helper,以便您可以使用任意输入表单快速获取结果。

尽管在使用reduce时并不总是这样,但下面的帮助器将允许将数组的第一个元素作为default值传递:

代码语言:javascript
复制
reducer = (list, func) => list.slice(1).reduce(func, list.slice(0, 1).pop())

以上代码仍然具有function依赖项,因此您仍然需要声明包装目标operator的特定函数

代码语言:javascript
复制
sum = list => reducer(list, (a, b) => a + b)
sum([1, 2, 3, 4, 5])

然后,您可以重新定义sum,例如,您看到的新输入格式将是向后兼容的。在这个示例中,使用了一个新的助手flat (现在仍处于实验阶段;添加了代码):

代码语言:javascript
复制
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):

代码语言:javascript
复制
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))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22303738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档