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

Elegantly calculate the minimum and maximum of a number array simultaneously

在Javascript中,给定一个简单的number[]数组,有没有一种优雅的方法可以同时计算最小值和最大值,或者return undefined如果数组是空的?

像这样:

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

抢先回复备注:

  1. 不是的重复,因为他实际上计算的不是同一个数组的最小值和最大值,而是最小值最多4个不同的数组。

  2. 我想在 one pass 中计算这些。不是 [Math.min(a), Math.max(a)].

  3. 我知道怎么做显而易见的方法:

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().

使用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"

您可以使用 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 的情况。

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

const a = [1, 2, 3];

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

console.log({min, max});

为什么不只是这个:

function minMax(arr) {
    arr = arr.sort((a, b) => a - b);
    return [arr.at(0), arr.at(-1)]
}
const a = [1, 2, 3];
const [ min, max ] = minMax(a);