【问题标题】:Recreating JavaScript Reduce function part 2重新创建 JavaScript Reduce 函数第 2 部分
【发布时间】:2016-01-01 17:56:33
【问题描述】:

这与我在这里重新创建的 reduce 函数有关,但有一个不同的问题:Recreating JavaScript's reduce function

我正在阅读 Eloquent JavaScript 并注意到他们用更少的代码以稍微不同的方式重新创建了 reduce 函数:

function reduce(array, combine, start) {
  var current = start;
  for (var i = 0; i < array.length; i++)
    current = combine(current, array[i]);
  return current;
}

console.log(reduce([1, 2, 3, 4], function(a, b) {
  return a + b;
}, 0)); // → 10

我注意到这仅在有开始时才有效。例如,如果我去掉了 start(0),它只是:

console.log(reduce([1, 2, 3, 4], function(a, b) {
  return a + b;
})); // NaN

它将返回 NaN。这对我来说没有意义,因为这本书说: “如果您的数组包含至少一个元素,您可以省略起始参数。该方法将数组的第一个元素作为其起始值,并从第二个元素开始减少。”

只有当我使用 if 语句调整它时,它才会产生带有或不带有 start(0) 的“10”。

function reduce(array, combine, start) {
  var current = start;

  for (var i = 0; i < array.length; i++)
    if(current !==undefined){
      current = combine(current, array[i]);
    }else{
      current=array[i]; 
    }

 return current;
}

我错过了什么?

【问题讨论】:

  • 显然这本书是错的。你试过检查errata吗?
  • 应该是var current = typeof start === 'undefined' ? array[0] : start;
  • @Louy 不完全是,因为你添加了第零个元素两次。
  • 是的,你是对的,他也应该改变循环开始索引
  • 我认为它应该是这样工作的。 Check the actual implementation here.

标签: javascript function underscore.js reduce


【解决方案1】:

根据MDN(此处为简化版),它应该是这样的:

function reduce(array, combine, start) {
  var current = start;
  var i = 0;
  if (arguments.length < 2) {
    while (array[i] === undefined) {
      i ++;
      if (array.length >= i) {
        throw new Error('Empty array with no initial value');
      }
    }
    current = array[i];
  }

  for (; i < array.length; ++ i) {
    if (array[i] === undefined) continue;
    if (current !== undefined) {
      current = combine(current, array[i]);
    } else {
      current=array[i]; 
    }
  }

  return current;
}

【讨论】:

  • 刚刚修复了一个无限循环。您需要抛出该错误。我认为书中的版本过于简化,在很多情况下都不起作用。不客气?
猜你喜欢
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 2015-07-28
  • 2019-10-25
  • 1970-01-01
  • 2011-04-19
相关资源
最近更新 更多