【问题标题】:How might I find the largest number contained in a JavaScript array?如何找到 JavaScript 数组中包含的最大数?
【发布时间】:2010-11-25 15:48:48
【问题描述】:

我有一个包含几个数字的简单 JavaScript 数组对象。

[267, 306, 108]

有没有一个函数可以在这个数组中找到最大的数?

【问题讨论】:

  • Math.max(...[267, 306, 108]);

标签: javascript algorithm arrays max


【解决方案1】:

Resig to the rescue:

Array.max = function( array ){
    return Math.max.apply( Math, array );
};

警告:由于the maximum number of arguments is as low as 65535 on some VMs,如果您不确定数组有那么小,请使用 for 循环。

【讨论】:

  • 啊,但现在它的 SO 质量贴纸 以一种略微歪斜的方式贴在它上面!
  • FWIW,如果性能是您解决方案中的一个因素,我会测试与您自己的易于编码的函数相比,以确保其性能良好。我们倾向于假设原生实现会更快;事实上,apply 电话的费用可以很容易地消除这一点。
  • 如果我的数组长度大于参数计数限制怎么办?
  • @CrescentFresh 根据此:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 它被硬编码为 65535。根据此:code.google.com/p/v8/issues/detail?id=172 并且知道参数被推入堆栈,我们知道它不是无限的
  • 另外,这种方法不可靠。如果您的数组大于最大堆栈大小,则会失败,导致RangeError: Maximum call stack size exceeded.
【解决方案2】:

你可以使用apply函数,调用Math.max

var array = [267, 306, 108];
var largest = Math.max.apply(Math, array); // 306

它是如何工作的?

apply 函数用于调用另一个函数,具有给定的上下文和参数,以数组的形式提供。 min 和 max 函数可以接受任意数量的输入参数:Math.max(val1, val2, ..., valN)

所以如果我们调用:

Math.min.apply(Math, [1, 2, 3, 4]);

apply 函数将执行:

Math.min(1, 2, 3, 4);

请注意,第一个参数上下文对于这些函数并不重要,因为它们是静态的。无论作为上下文传递什么,它们都将起作用。

【讨论】:

  • 哇,你付出了很多努力:D
  • 太好了。但是如果我的数组长度超过参数大小限制(函数)怎么办?然后呢?
  • 我比其他答案更喜欢这个答案,因为它解释了一切的作用和原因。 +1
【解决方案3】:

最简单的语法,新的spread operator:

var arr = [1, 2, 3];
var max = Math.max(...arr);

来源:Mozilla MDN

【讨论】:

【解决方案4】:

我不是 JavaScript 专家,但我想看看这些方法是如何叠加的,所以这对我来说是个好习惯。我不知道这在技术上是否是对这些进行性能测试的正确方法,但我只是一个接一个地运行它们,正如您在我的代码中看到的那样。

排序并获得第 0 个值是迄今为止最糟糕的方法(它会修改数组的顺序,这可能是不可取的)。对于其他人来说,除非您说的是数百万个索引,否则差异可以忽略不计。

使用 100,000 索引的随机数数组运行五次的平均结果:

  • reduce 运行耗时 4.0392 毫秒
  • Math.max.apply 运行耗时 3.3742 毫秒
  • 排序和获取第 0 个值需要 67.4724 毫秒 运行
  • reduce() 中的 Math.max 需要 6.5804 毫秒 运行
  • 自定义 findmax 函数耗时 1.6102 毫秒 运行

var performance = window.performance

function findmax(array)
{
    var max = 0,
        a = array.length,
        counter

    for (counter=0; counter<a; counter++)
    {
        if (array[counter] > max)
        {
            max = array[counter]
        }
    }
    return max
}

function findBiggestNumber(num) {
  var counts = []
  var i
  for (i = 0; i < num; i++) {
      counts.push(Math.random())
  }

  var a, b

  a = performance.now()
  var biggest = counts.reduce(function(highest, count) {
        return highest > count ? highest : count
      }, 0)
  b = performance.now()
  console.log('reduce took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest2 = Math.max.apply(Math, counts)
  b = performance.now()
  console.log('Math.max.apply took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest3 = counts.sort(function(a,b) {return b-a;})[0]
  b = performance.now()
  console.log('sorting and getting the 0th value took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest4 = counts.reduce(function(highest, count) {
        return Math.max(highest, count)
      }, 0)
  b = performance.now()
  console.log('Math.max within reduce() took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest5 = findmax(counts)
  b = performance.now()
  console.log('custom findmax function took ' + (b - a) + ' ms to run')
  console.log(biggest + '-' + biggest2 + '-' + biggest3 + '-' + biggest4 + '-' + biggest5)

}

findBiggestNumber(1E5)

【讨论】:

  • 对我来说,这是这个问题的最佳答案。
  • 我已经为上述内容制作了jsperf tests
【解决方案5】:

我发现对于更大的数组(约 100k 个元素),使用简单的 for 循环简单地迭代数组实际上是值得的,性能比 Math.max.apply() 好约 30%:

function mymax(a)
{
    var m = -Infinity, i = 0, n = a.length;

    for (; i != n; ++i) {
        if (a[i] > m) {
            m = a[i];
        }
    }

    return m;
}

Benchmark results

【讨论】:

  • FWIW,现在在 Chrome 31 上达到 84%。
【解决方案6】:

您可以按降序对数组进行排序并获得第一项:

[267, 306, 108].sort(function(a,b){return b-a;})[0]

【讨论】:

  • 我假设您也可以只排序并获取最后一项...?
  • @Shog9:可以,但您需要自己指定比较函数:sort(function(a,b){return b-a;})
  • 啊。我的想法更像是:[...].sort().pop()
  • "查找数字需要 order-n,排序需要 order(n log n) 到 order(n squared),取决于使用的排序算法" - webmasterworld.com/forum91/382.htm
  • 还请记住,这会对数组进行排序,这可能是也可能不是所需的副作用。 apply 解决方案性能更好,没有副作用。
【解决方案7】:

用途:

var arr = [1, 2, 3, 4];

var largest = arr.reduce(function(x,y) {
    return (x > y) ? x : y;
});

console.log(largest);

【讨论】:

  • 如果我先看到这个答案(目前在列表的底部),我会节省两个小时。
  • Math.max 方法可能是最标准的,但是当数组太大(500K)时,我遇到了堆栈溢出。这个答案快速有效,是我最终自己使用的答案,所以我赞成这个答案。
【解决方案8】:

使用Array.reduce:

[0,1,2,3,4].reduce(function(previousValue, currentValue){
  return Math.max(previousValue,currentValue);
});

【讨论】:

  • 初始值应设置为-Infinity
  • @Jack,为什么需要这个?即使有一个全为负数的数组,我也会得到一个有效的结果。
  • 这是数组为空的边缘情况。
【解决方案9】:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

const inputArray = [ 1, 3, 4, 9, 16, 2, 20, 18];
const maxNumber = Math.max(...inputArray);
console.log(maxNumber);

【讨论】:

【解决方案10】:

以简单和手动的方式查找最大值和最小值。这段代码比Math.max.apply快很多;我已经在数组中尝试了多达 1000k 个数字。

function findmax(array)
{
    var max = 0;
    var a = array.length;
    for (counter=0;counter<a;counter++)
    {
        if (array[counter] > max)
        {
            max = array[counter];
        }
    }
    return max;
}

function findmin(array)
{
    var min = array[0];
    var a = array.length;
    for (counter=0;counter<a;counter++)
    {
        if (array[counter] < min)
        {
            min = array[counter];
        }
    }
    return min;
}

【讨论】:

  • 如果数组中只有负数,findmax() 会给出错误的结果; findmin() 为空数组提供了错误的结果。
【解决方案11】:

几乎所有答案都使用Math.max.apply(),这很好用,但也有局限性。

函数参数被放置在堆栈上,它有一个缺点 - 一个限制。因此,如果您的数组大于限制,它将失败并显示RangeError: Maximum call stack size exceeded.

要查找调用堆栈大小,我使用了以下代码:

var ar = [];
for (var i = 1; i < 100*99999; i++) {
  ar.push(1);
  try {
    var max = Math.max.apply(Math, ar);
  } catch(e) {
    console.log('Limit reached: '+i+' error is: '+e);
    break;
  }
}

在我的机器上,它在 Firefox 上被证明是最大的 - 591519。这意味着如果您的数组包含超过 591519 个项目,Math.max.apply() 将导致 RangeError

这个问题的最佳解决方案是迭代方式(信用:https://developer.mozilla.org/):

max = -Infinity, min = +Infinity;

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max)
    max = numbers[i];
  if (numbers[i] < min)
    min = numbers[i];
}

我已经在我的博客here 上写过这个问题。

【讨论】:

  • 这不公平。我想在这里得到答案,而不是另一个第三方资源的链接。尤其是当它与“这里的一切都很糟糕,但是去,看,在我的博客上真是太棒了......”结合在一起时。
  • @SergeyOrshanskiy 一个指向第三方的链接非常有效,以防它更新了新的见解和解决方案。也没有必要感到被冒犯。人们也只想解决你的问题。我也想解决它,所以我在我的博客上写了它
【解决方案12】:

要查找数组中的最大数,您只需使用Math.max(...arrayName);。它的工作原理是这样的:

let myArr = [1, 2, 3, 4, 5, 6];
console.log(Math.max(...myArr));

要了解有关Math.max 的更多信息: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

【讨论】:

    【解决方案13】:

    简单的一个班轮

    [].sort().pop()
    

    【讨论】:

      【解决方案14】:

      是的,当然存在Math.max.apply(null,[23,45,67,-45]),结果是返回67

      【讨论】:

        【解决方案15】:

        不要忘记可以使用Function.prototype.bind 完成换行,为您提供“全原生”函数

        var aMax = Math.max.apply.bind(Math.max, Math);
        aMax([1, 2, 3, 4, 5]); // 5
        

        【讨论】:

          【解决方案16】:

          您还可以扩展 Array 以拥有此功能并使其成为每个数组的一部分。

          Array.prototype.max = function(){return Math.max.apply( Math, this )};
          myArray = [1,2,3];
          
          console.log( myArray.max() );
          

          【讨论】:

          • 效率极低。
          • @FrankSchmitt,谢谢,我同意。原始答案不是一个好的解决方案。默认情况下排序不会对数字进行排序,它将元素视为字符串。编辑了我的答案以获得正确的排序。
          • 那不是我的意思。对数组进行排序以找到最大值本身是非常低效的,因为它至少需要 N log N 操作,而找到最大值可以在 N 操作中完成。
          【解决方案17】:

          你也可以使用forEach:

          var maximum = Number.MIN_SAFE_INTEGER;
          
          var array = [-3, -2, 217, 9, -8, 46];
          array.forEach(function(value){
            if(value > maximum) {
              maximum = value;
            }
          });
          
          console.log(maximum); // 217

          【讨论】:

            【解决方案18】:

            使用 - Array.prototype.reduce() 很酷!

            [267, 306, 108].reduce((acc,val)=&gt; (acc&gt;val)?acc:val)

            其中 acc = 累加器val = 当前值

            var a = [267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val);
            
            console.log(a);

            【讨论】:

              【解决方案19】:

              关于如何使用三元运算符的递归方法

              const findMax = (arr, max, i) => arr.length === i ? max :
                findMax(arr, arr[i] > max ? arr[i] : max, ++i)
              
              const arr = [5, 34, 2, 1, 6, 7, 9, 3];
              const max = findMax(arr, arr[0], 0)
              console.log(max);

              【讨论】:

                【解决方案20】:

                你可以试试这个,

                var arr = [267, 306, 108];
                var largestNum = 0;
                for(i=0; i<arr.length; i++) {
                   if(arr[i] > largest){
                     var largest = arr[i];
                   }
                }
                console.log(largest);
                

                【讨论】:

                  【解决方案21】:

                  我刚开始使用 JavaScript,但我认为这种方法会很好:

                  var array = [34, 23, 57, 983, 198];
                  var score = 0;
                  
                  for(var i = 0; i = array.length; i++) {
                    if(array[ i ] > score) {
                      score = array[i];
                    }
                  }
                  

                  【讨论】:

                  • 如果array 只包含负数,这将有问题。
                  【解决方案22】:

                  var nums = [1,4,5,3,1,4,7,8,6,2,1,4];
                  nums.sort();
                  nums.reverse();
                  alert(nums[0]);

                  最简单的方法:

                  var nums = [1,4,5,3,1,4,7,8,6,2,1,4]; nums.sort(); nums.reverse(); alert(nums[0]);
                  

                  【讨论】:

                    【解决方案23】:

                    运行这个:

                    Array.prototype.max = function(){
                        return Math.max.apply( Math, this );
                    };
                    

                    现在试试[3,10,2].max() 返回10

                    【讨论】:

                      【解决方案24】:

                      使用冒泡排序查找最大值和最小值

                          var arr = [267, 306, 108];
                      
                          for(i=0, k=0; i<arr.length; i++) {
                            for(j=0; j<i; j++) {
                              if(arr[i]>arr[j]) {
                                k = arr[i];
                                arr[i] = arr[j];
                                arr[j] = k;
                              }
                            }
                          }
                          console.log('largest Number: '+ arr[0]);
                          console.log('Smallest Number: '+ arr[arr.length-1]);

                      【讨论】:

                      • (1) Javascript 数组已经具有 O(n log n) 排序函数。 (2) 冒泡排序是 O(n^2)。 (3)求最小值和最大值是O(n)。
                      【解决方案25】:

                      试试这个

                      function largestNum(arr) {
                        var currentLongest = arr[0]
                      
                        for (var i=0; i< arr.length; i++){
                          if (arr[i] > currentLongest){
                            currentLongest = arr[i]
                          }
                        }
                      
                        return currentLongest
                      }
                      

                      【讨论】:

                      • 这个答案与这个页面上的许多其他答案有很大不同吗?
                      【解决方案26】:

                      根据@Quasimondo 的comment,这似乎在很大程度上被遗漏了,下面似乎有最好的性能,如下所示:https://jsperf.com/finding-maximum-element-in-an-array。请注意,虽然对于问题中的数组,性能可能没有显着影响,但对于大型数组,性能变得更加重要,如果数组长度超过 65535,as noted 使用 Math.max() 甚至不起作用。请参阅还有this answer

                      function largestNum(arr) {
                          var d = data;
                          var m = d[d.length - 1];
                          for (var i = d.length - 1; --i > -1;) {
                            if (d[i] > m) m = d[i];
                          }
                          return m;
                      }
                      

                      【讨论】:

                        【解决方案27】:

                        一个for/of循环解决方案:

                        const numbers = [2, 4, 6, 8, 80, 56, 10];
                        
                        
                        const findMax = (...numbers) => {
                          let currentMax = numbers[0]; // 2
                        
                          for (const number of numbers) {
                            if (number > currentMax) {
                              console.log(number, currentMax);
                              currentMax = number;
                            }
                          }
                          console.log('Largest ', currentMax);
                          return currentMax;
                        };
                        
                        findMax(...numbers);

                        【讨论】:

                          【解决方案28】:

                          在多维数组中求最大数

                          var max = [];
                          
                          for(var i=0; arr.length>i; i++ ) {
                          
                             var arra = arr[i];
                             var largest = Math.max.apply(Math, arra);
                             max.push(largest);
                          }
                          return max;
                          

                          【讨论】:

                          • 始终建议在您的代码中添加一些详尽的解释,尤其是在已经有多个其他答案的情况下。为什么这个不同/更好?
                          • @Bowdzone,感谢您的评论。这种方法非常基本,只需了解一些方法即可轻松理解。
                          • 这里不返回最大数,而是返回多维数组中每个数组的最大数的数组。您需要添加例如var tmax = Math.max.apply(Math, max),或者更好的是,使用循环函数的闭包,例如在stackoverflow.com/a/54980012/7438857。有了这个修改,最好回答一个单独的问题,你如何“在多维数组中找到最大的数”,或者stackoverflow.com/questions/32616910/…。在制品:jsfiddle.net/jamesray/3cLu9for/8.
                          • stackoverflow.com/a/32617019/7438857 是对正确问题的更好答案,虽然此答案没有回答上述问题,但它返回多维数组中每个数组中的最大数。
                          【解决方案29】:

                          我在数组中返回最大数字的解决方案。

                          const largestOfFour = arr => {
                              let arr2 = [];
                              arr.map(e => {
                                  let numStart = -Infinity;
                                  e.forEach(num => {
                                      if (num > numStart) {
                                          numStart = num;
                          
                                      }
                                  })
                                  arr2.push(numStart);
                              })
                              return arr2;
                          }
                          

                          【讨论】:

                            【解决方案30】:

                            应该很简单:

                            var countArray = [1,2,3,4,5,1,3,51,35,1,357,2,34,1,3,5,6];
                            
                            var highestCount = 0;
                            for(var i=0; i<=countArray.length; i++){    
                                if(countArray[i]>=highestCount){
                                highestCount = countArray[i]
                              }
                            }
                            
                            console.log("Highest Count is " + highestCount);
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2021-06-07
                              • 1970-01-01
                              • 2015-10-30
                              • 1970-01-01
                              • 2021-11-10
                              • 2023-01-13
                              相关资源
                              最近更新 更多