JS中大数组的最大/最小值

6

我需要计算一个大数组的最小值和最大值。我知道可以使用Math.max.apply()函数,但在处理大数组时会出现栈溢出异常。有没有简单的解决方案?


1
显而易见的问题:有多大? - gdoron
like 100 000 elements - Alexey Timanovsky
1
为什么要在客户端处理如此大量的数据? - George Cummins
5
我没有提到客户端。 - Alexey Timanovsky
是的,但在服务器端有比JavaScript更好的方法,所以我做了一个假设。为什么选择JavaScript? - George Cummins
实际上,这是CLI脚本的一部分。我更喜欢Python,但是1)我的团队决定使用JS 2)我们使用Azure和Windows,而Node最容易设置为具有跨平台脚本工具。 - Alexey Timanovsky
7个回答

6
  1. Sort the array by using sort() method it sorts array by using quicksort algorithm

  2. Since array is sorted in ascending order then the last element is the max

    var arr = [1,4,6,4, ...];
    arr.sort((a, b) => a - b);
    var max = arr[arr.length - 1];
    

2
你的回答让我感到很愚蠢 :(. 事实上,我已经有了排好序的数组。这就是你需要代码审查的原因... - Alexey Timanovsky
保持DRY原则 = 不要重复自己 :) - Nick
5
只有在你打算对数组进行一些二分查找[O(log n)]的情况下,才值得对数组进行排序。如果你想获取最大值和最小值,最好遍历每个元素,因为O(n)比O(n log n)更快。对于许多大型数组而言,这可能很重要... - David Sherret
1
当然。我已经对数组进行了排序,以计算百分位数。拥有最小值/最大值是一个很好的副作用 :) - Alexey Timanovsky
你可以通过按降序排序来稍微简化这个过程,这样只需要获取第一个元素即可。即 arr.sort((a, b) => b - a)[0] - micahbf

3
Array.prototype.min = function() {
    var r = this[0];
    this.forEach(function(v,i,a){if (v<r) r=v;});
    return r;
};

来自JavaScript:min&max数组值?,该问题的其他解决方案在此讨论。

提醒一下:我只是谷歌了“max min large array”,并将其作为第一个结果找到...


我看到了那个帖子,但没有全部阅读,谢谢 :) - Alexey Timanovsky
参考资料,解决大数组问题的确切答案是这个:https://dev59.com/WXI-5IYBdhLWcg3wy70d#8986992 - apsillers

2

为什么不直接遍历整个数组?

var max = Number.MIN_VALUE, min = Number.MAX_VALUE;
for (var i = 0, len=list.length; i < len; i++) {
   if (list[i] > max) max = list[i];
   if (list[i] < min) min = list[i];
}

编辑:

针对最大值:

if (typeof Array.prototype.GetMax === "undefined") {
    Array.prototype.GetMax = function() {
        var max = Number.MAX_VALUE;
        for (var i = 0, len=this.length; i < len; i++) {
           if (this[i] > max) max = this[i];
        }
        return max;
    }
}

对于 min:

if (typeof Array.prototype.GetMin === "undefined") {
    Array.prototype.GetMin = function() {
        var min = Number.MIN_VALUE;
        for (var i = 0, len=this.length; i < len; i++) {
           if (this[i] < min) min = this[i];
        }
        return min;
    }
}

对于两者:

if (typeof Array.prototype.GetMaxMin === "undefined") {
    Array.prototype.GetMaxMin = function() {
        var max = Number.MIN_VALUE, min = Number.MAX_VALUE;
        for (var i = 0, len=this.length; i < len; i++) {
            if (this[i] > max) max = this[i];
            if (this[i] < min) min = this[i];
        }
        return { Max: max, Min: min};
    }
}

只需使用 Number.MAX_VALUE/Number.MIN_VALUE 初始化 min/max,然后您就可以删除第一个 if 条件。 - Sirko
这可以添加到array.prototype中,使其更易于使用。 - Yuriy Galanter
我从来不知道 Javascript 中有 Number.MAX_VALUE 这个东西。酷! - David Sherret
顺便提一下,我会使用第一个元素进行初始化,以支持非数字值。 - RiaD

0

我可以假设你已经考虑过这个问题:

var maxSoFar = -9999999;
for (var i = 0; i < array.length ; ++i) {
    if (array[i] > maxSoFar) {
        maxSoFar = array[i];
    }
    ... similar for minSoFar ...
}

是的,我想...我正在寻找更多功能风格的东西 :) - Alexey Timanovsky

0

试试这个

var arr = [];
for(var i=1000000;i>0;i--)
{
    arr.push(i);
}
//we create a copy of the original array through arr.concat() since we do not want to change the original sorting order of the array
//we pass a function in the sort method as by default it sorts alphabetically instead of numerically. So 99 will be smaller than 100.
var arrMaxMin = arr.concat().sort(function(a,b){return a-b});

arrMaxMin[0]; //min
arrMaxMin[arrMaxMin.length - 1]; //max

0

嘿,为什么不将数组切成较小的数组,然后在这些数组上轻松使用Math.max.apply(Math,individual arrays)。但是请记住,一旦获得所需的最大值,必须重新将所有子数组初始化为null,以便释放内存。


0

这正是reduce所用之处:

function max(arr) {
  if (arr.length === 0) {
    return NaN // or whatever answer you want for an empty array, or throw an error.
  }
  return arr.reduce((a, b) => Math.max(a, b), -Infinity)
}
console.log(max([...new Array(100000).keys()]))

请注意,[...new Array(100000).keys()]只是现代浏览器中一种制作包含数字0到999999的巨大数组的花哨方式。而max函数本身在过去20年内的任何编程环境中都可以运行。
你也可以将其简化为一行代码:
arr.reduce((cur, val, i) => i === 0 ? val : Math.max(cur, val), NaN)

这里NaN是当数组为空时返回的值。

甚至更多。

arr.reduce((a, b) => Math.max(a, b), -Infinity)

虽然这将对空数组返回-Infinity

最后,仅仅这样做可能很诱人:

arr.reduce(Math.max, -Infinity)  //don't do this!!

但这样做是行不通的。这是因为reduce调用它的函数(Math.max)带有4个参数,其中一个是原始数组,所以对它们进行Math.max将始终导致NaN


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接