6

我正在尝试决定是否将 Javascript 中的 reduce() 方法用于我需要编写的函数,就像这样

var x = [some array], y = {};
for (...) {
    someOperation(x[i]);
    y[x[i]] = "some other value";
}

现在这显然可以用以下方式写成一个 reduce() 函数:

x.reduce(function(prev, current, index, arr) {
    someOperation(current);
    prev[current] = "some other value";
    return prev;
}, {})

或类似的东西。两者之间有什么性能或其他区别吗?或者其他一些原因(例如浏览器支持),因为在 Web 编程环境中应该优先考虑哪一个?谢谢。

4

4 回答 4

4

尽管我更喜欢这些操作(reduce、map、filter 等),但使用它们仍然不可行,因为某些浏览器在其实现中不支持它们。当然,您可以通过扩展Array原型来“修补”它,但这也带来了很多麻烦。

我认为这些函数本质上没有任何问题,而且我认为它们可以生成更好的代码,但现在最好不要使用它们。一旦更高比例的人口使用支持这些功能的浏览器,我认为它们将是公平的游戏。

就性能而言,由于函数调用的开销,这些可能会比手动编写的 for 循环慢。

于 2011-06-16T01:35:18.467 回答
4

mapand filterand reduceand forEachand ...(更多信息:https ://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array#Iteration_methods )比普通循环要好得多,因为:

  1. 他们更优雅
  2. 他们鼓励函数式编程(参见函数式编程的好处)
  3. 无论如何,您都需要编写函数并将其作为参数、迭代变量传递给它们。这是因为 javascript 没有块作用域。函数喜欢map并使reduce您的工作变得如此轻松,因为它们会自动设置您的迭代变量并将其传递给您的函数。

IE9 声称支持这些。它们在官方的 javascript/ecmascript 规范中。如果您关心使用 IE8 的人,那是您的特权。如果您真的在乎,您可以通过仅覆盖Array.prototypeIE8 和更早版本来破解它,以“修复”IE8 和更早版本。

于 2011-07-18T07:22:20.607 回答
2

reduce 用于从数组中返回一个值,作为顺序处理先前元素的结果的结果。

reduceRight 做同样的事情,但从最后开始并向后工作。

map 用于返回一个数组,其成员都已通过函数传递。

两种方法都不会影响数组本身。

var A1= ['1', '2', '3', '4', '5', '6', '7','8'];

// 这种对 map 的使用返回一个新的原始元素数组,转换为数字-

A1=A1.map(数字); // >> A1 的每个元素都转换为数字

// 这减少了数组元素的总数-

var A1sum= A1.reduce(function(a, b){ return a+b;});

// A1sum>>返回值:(数字)36

旧版浏览器不支持它们,因此您需要提供它们的替代品。如果您所做的一切都可以在一个简单的循环中复制,那是不值得的。

计算总体的标准差是可以有效使用 map 和 reduce 的一个例子——

Math.mean= function(array){
    return array.reduce(function(a, b){ return a+b; })/array.length;
}
Math.stDeviation=function(array){
    var mean= Math.mean(array);
    dev= array.map(function(itm){return (itm-mean)*(itm-mean); });
    return Math.sqrt(dev.reduce(function(a, b){ return a+b; })/array.length);
}


var A2= [6.2, 5, 4.5, 6, 6, 6.9, 6.4, 7.5];
alert ('mean: '+Math.mean(A2)+'; deviation: '+Math.stDeviation(A2))
于 2011-06-16T02:11:17.090 回答
0

kennebec - 进展顺利,但您的stDeviation函数调用reduce两次,并在只需要一次调用 reduce 时映射一次使得它更快):

Math.stDev = function (a) {
    var n = a.length;
    var v = a.reduce(function (v, x) {
      v[0] += x * x;
      v[1] += x;
      return v;
    }, [0,0]);
    return Math.sqrt( (v[0] - v[1]*v[1] / n) / n );
}

分配给v[1]时应转换为数字,以确保字符串数字不会与结果混淆,并且在大多数情况下,最后一行中的除数应该是 (n - 1),但这取决于 OP . :-)

于 2011-06-16T04:13:46.553 回答