优雅地同时计算数字数组的最小值和最大值

Posted

技术标签:

【中文标题】优雅地同时计算数字数组的最小值和最大值【英文标题】:Elegantly calculate the minimum and maximum of a number array simultaneously 【发布时间】:2020-10-14 19:34:33 【问题描述】:

javascript 中,给定一个简单的 number[] 数组,是否有一种优雅的方法可以同时计算最小值和最大值,或者如果数组为空则返回 undefined

类似这样的:

const a = [1, 2, 3];
const (min, max) = minMax(a);

先发制人的回应说明:

    不是与this question的重复,因为他实际上并不是在计算同一个数组的最小值和最大值,而是计算4个不同数组的最小值最大值.

    我想一次性计算出这些。不是[Math.min(a), Math.max(a)]

    我知道该怎么做:

let min = undefined;
let max = undefined;
for (const x of array) 
  min = min === undefined ? x : Math.min(min, x);
  max = max === undefined ? x : Math.max(max, x);

我想知道是否有更优雅的东西,例如使用Array.reduce()

【问题讨论】:

没有Math.reduce函数,你的意思是Array.reduce吗?如果是这样,只需将 for of 循环放入 reduce 函数中即可。 啊是啊,谢谢!而且它不是那么简单,因为reduce 的输入和输出必须是相同的类型。我可以做array.map(x => [x, x]).reduce(...),但是euurgh。不是我对优雅的看法。 array.reduce(([min,max], x)=>[Math.min(min,x),Math.max(max,x)],[,,].fill(array[0]))? 【参考方案1】:

您可以使用Array.reduce() 减少任何类型的结果,它不必是相同的类型。例如,将一个数字数组缩减为两个数字的输出数组,最小值和最大值:

const minMax = arr => 
  arr.reduce(([min,max=min],num) => [Math.min(num,min),Math.max(num,max)], arr);

const a = [5,2,6,3,3,1,1];
const [min,max] = minMax(a);

console.log("min",min,"max",max);

reduce 是由数组本身播种的,为了简洁起见,因为其他任何东西都有些不必要。由于解构,这会弄乱长度为 1 的数组,因此 max=min 用于将 max 设置为等于第一个元素作为后备。所以数组长度为 1 或 0 的情况都会被处理。

【讨论】:

其实没关系,但是如果数组长度为1就会失败,加默认值,max=min]什么的 只需将 max 更改为 max=min,因此默认为第一个值。你的答案在技术上比他的更正确,因为它处理空集 @user120242 嗯! TIL 关于解构参数的默认值!谢谢,确定会出错 我将在这里发表基于个人观点和有争议的评论,但我建议将箭头后面的部分放在换行符上。它被截断了,因为这条线太长了,即使它完全可见,也很难像那样阅读。让它看起来很模糊 这就是我想的那种事情!也许有点聪明 - 我花了几分钟才注意到数组解构 - 但很好的答案!【参考方案2】:

使用Array.reduce 并且只对数组进行一次迭代。我正在使用数组破坏赋值从函数中传回 minmax 值(因为 JS 没有元组类型)。我还在检查数组的边缘情况是否为空:

function minMax(array) 
  if (array.length == 0) 
    return [undefined, undefined];
  
  return array.reduce(([min, max], val) => 
    return [Math.min(min, val), Math.max(max, val)];
  , [Number.MAX_VALUE, Number.MIN_VALUE]);


function testMinMax(array) 
  let [min, max] = minMax(array);
  console.log(min, max);


testMinMax([]); // logs "undefined undefined"
testMinMax([1]); // logs "1 1"
testMinMax([1, 2, 3, 4, 5]); // logs "1 5"

【讨论】:

你也可以使用[Infinity, -Infinity]作为默认值;) 不错但是当数组为空时它不会返回undefined。这很棘手,因为Math.max(undefined, 10)NaN @Timmmm 我已经更新了我的答案以检查数组的边缘情况是否长度为 0 或 1。 您不需要数组长度为 1 的特殊情况,但如果将其删除,我猜这是可以做到的最好的。 @Timmmm 是的,你是对的,我再次更新了我的答案。【参考方案3】:

扩展运算符结合 Math.min 和 Math.max

const a = [1, 2, 3];

const [min, max] = [Math.min(...a), Math.max(...a)];

console.log(min, max);

【讨论】:

我已经说过我对这个问题的答案不感兴趣。

以上是关于优雅地同时计算数字数组的最小值和最大值的主要内容,如果未能解决你的问题,请参考以下文章

计算用户在Java中输入的一系列数字的总和、算术平均值、最小值和最大值? [关闭]

Laravel 验证检查数组大小的最小值和最大值

Azure搜索:价格范围 - 最小值和最大值计算

NumPy实现数据的聚合,计算最大值,最小值和其他值

输入类型=具有最小值和最大值的文本模式数字

尝试根据 ID 计算一系列数据的平均值、最小值和最大值