【问题标题】:Reduce of empty array with no initial value after testing a specific use case测试特定用例后减少没有初始值的空数组
【发布时间】:2018-04-25 12:34:45
【问题描述】:

变量min 将包含给定数组中4 个最小项的总和。 变量 max 将包含给定数组中 4 个最大项的总和。

JS:

function main() {
  const arr = [1, 2, 3, 4, 5]
  const min = arr.sort().filter((element, index, array) => element !== array[array.length - 1]).reduce((accumulator, currentValue) => {
    return accumulator + currentValue
  })
  const max = arr.sort().filter((element, index, array) => element !== array[0]).reduce((accumulator, currentValue) => {
    return accumulator + currentValue
  })
  console.log(min, max)
}

main()

正如预期的那样,[1,2,3,4,5] 将导致 10、14。但是,如果给定数组是 [5,5,5,5,5],则程序将返回 TypeError: Reduce of empty array with no initial value

这是为什么?

谢谢。

【问题讨论】:

  • 为什么?因为您没有在 .reduce 中指定初始值 - 只需将 0 作为该函数的第二个参数。 // 此外,您的过滤逻辑与您提供的目标描述不匹配 - 但这完全是另一回事。
  • 我想你忘了提到数组包含5 元素?

标签: javascript sorting filter functional-programming reduce


【解决方案1】:

当所有元素都相同时, 对于所有元素,条件element !== array[array.length - 1] 将为假,因为所有元素都与最后一个相同。 因此filter(...) 的结果将是一个空数组, 所以你得到了你得到的错误。

事实上,这个实现是有缺陷的。 最好使用 index 而不是元素值:

function main(arr) {
  const count = 4;

  const sorted = arr.sort((a, b) => a - b);

  const sum = (accumulator, currentValue) => accumulator + currentValue;

  const min = sorted
    .filter((element, index) => index < count)
    .reduce(sum);

  const max = sorted
    .filter((element, index) => index >= arr.length - count)
    .reduce(sum);

  console.log(min, max);
}

main([1, 2, 3, 4, 5]);
main([5, 5, 5, 5, 5]);

我还进行了一些其他改进:

  • 将数组作为函数的参数,方便测试
  • 不要对数组进行两次排序,一次就够了
  • 正如@Andrew 在评论中指出的那样,arr.sort() 不能正确地对整数进行排序,您需要将比较器函数传递给它以获得预期的效果
  • 减少重复逻辑:提取sum函数和count变量
  • 用内联的 lambda 表达式替换代码块

【讨论】:

  • 感谢@Andrew,我忽略了这一点,现在已修复
  • 我们也可以缓存arr.length吗?
  • @CodeYogi 任何可能带来的改进,我认为都可以忽略不计。
  • @CodeYogi arr.length 是数组对象的一个​​属性。从这个意义上说,它已经被“缓存”了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
  • 2016-11-01
  • 1970-01-01
  • 2015-11-10
  • 1970-01-01
  • 2020-01-18
  • 2018-10-06
相关资源
最近更新 更多