Làm cách nào tôi có thể tìm thấy số lớn nhất có trong một mảng JavaScript?


206

Tôi có một đối tượng JavaScript Array đơn giản chứa một vài số.

[267, 306, 108]

Có một chức năng sẽ tìm thấy số lượng lớn nhất trong mảng này?


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

Câu trả lời:


315

Resig để giải cứu:

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

Cảnh báo : vì số lượng đối số tối đa thấp nhất là 65535 trên một số máy ảo , hãy sử dụng vòng lặp for nếu bạn không chắc chắn mảng đó nhỏ.


15
À, nhưng bây giờ nó có Nhãn dán Chất lượng SO được dán vào nó theo kiểu hơi quanh co!
Shog9

2
FWIW, nếu hiệu suất là một yếu tố trong giải pháp của bạn, tôi sẽ kiểm tra xem so với chức năng dễ mã hóa của bạn để đảm bảo nó hoạt động tốt. Chúng tôi có xu hướng cho rằng việc thực hiện riêng sẽ nhanh hơn; trong thực tế, chi phí của applycuộc gọi có thể rửa trôi rất dễ dàng.
TJ Crowder

2
Nếu chiều dài mảng của tôi lớn hơn giới hạn đếm tham số thì sao?
lukas.pukenis

3
@CrescentFresh theo này: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... nó là hardcoded đến 65535. Theo này: code.google.com/p/v8/issues/detail?id = 172 và theo hiểu biết rằng các đối số được đẩy lên ngăn xếp, chúng tôi biết rằng nó không giới hạn
lukas.pukenis

9
Ngoài ra, phương pháp này không mạnh mẽ. Không thành công nếu mảng của bạn lớn hơn kích thước ngăn xếp tối đa dẫn đếnRangeError: Maximum call stack size exceeded.
Đánh dấu Lundin

197

Bạn có thể sử dụng hàm áp dụng, để gọi Math.max :

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

Làm thế nào nó hoạt động?

Hàm áp dụng được sử dụng để gọi một hàm khác, với ngữ cảnh và đối số đã cho, được cung cấp dưới dạng một mảng. Các hàm tối thiểu và tối đa có thể lấy một số lượng đối số đầu vào tùy ý: Math.max (val1, val2, ..., valN)

Vì vậy, nếu chúng ta gọi:

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

Hàm áp dụng sẽ thực thi:

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

Lưu ý rằng tham số đầu tiên, bối cảnh, không quan trọng đối với các hàm này vì chúng là tĩnh, chúng sẽ hoạt động bất kể những gì được truyền dưới dạng bối cảnh.


2
Whoa bạn đưa ra câu trả lời của bạn với rất nhiều nỗ lực: D
ShrekOverflow

1
Thật tuyệt. Nhưng nếu chiều dài mảng của tôi vượt quá giới hạn kích thước tham số (của hàm) thì sao? Sau đó thì sao?
lukas.pukenis

1
Tôi thích câu trả lời này tốt hơn những câu hỏi khác vì nó giải thích mọi thứ làm gì và tại sao. +1
Marvin

59

Cú pháp dễ nhất, với toán tử trải rộng mới :

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

Nguồn: Mozilla MDN


2
Tuy nhiên, cả lây lan (...) và áp dụng sẽ thất bại hoặc trả về kết quả sai nếu mảng có quá nhiều phần tử developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ tựa
Green

@Green FWIW, giới hạn số lượng tham số là 65536 (ít nhất là trên Chrome) ([nguồn ( bug.webkit.org/show_orms.cgi?id=80797)] ). Vì vậy, nếu mảng của bạn có nhiều hơn 65536 phần tử, câu trả lời này sẽ không hoạt động.
mgthomas99

4
65536 phải là đủ cho bất cứ ai
vsync

41

Tôi không phải là chuyên gia về JS, nhưng tôi muốn xem các phương thức này xếp chồng lên nhau như thế nào, vì vậy đây là cách thực hành tốt cho tôi. Tôi không biết liệu đây có phải là cách đúng đắn để kiểm tra hiệu năng hay không, nhưng tôi chỉ chạy chúng ngay sau đó, như bạn có thể thấy trong mã của mình.

Sắp xếp và nhận giá trị 0 là phương pháp tồi tệ nhất (và nó sửa đổi thứ tự của mảng của bạn, điều này có thể không được mong muốn). Đối với những người khác, sự khác biệt là không đáng kể trừ khi bạn nói hàng triệu chỉ số.

Kết quả trung bình của năm lần chạy với một dãy số ngẫu nhiên 100.000 chỉ số:

  • giảm mất 4.092ms để chạy
  • Math.max.apply mất 3,3742ms để chạy
  • sắp xếp và nhận giá trị thứ 0 mất 67,4724ms để chạy
  • Math.max trong vòng giảm () mất 6,5804ms để chạy
  • chức năng findmax tùy chỉnh mất 1.6102ms để chạy

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)

7
Đối với tôi, đây là câu trả lời tốt nhất cho câu hỏi này.
rzelek

1
Tôi đã thực hiện jsperf testscho những điều trên
vsync

37

Tôi đã thấy rằng đối với các mảng lớn hơn (~ 100 nghìn phần tử), nó thực sự trả tiền để đơn giản lặp lại mảng với một forvòng lặp khiêm tốn , thực hiện tốt hơn ~ 30% so với Math.max.apply():

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

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

    return m;
}

Kết quả điểm chuẩn


3
FWIW, hiện đã lên tới 84% trên Chrome 31.
Ilan Biala

31

Bạn có thể sắp xếp mảng theo thứ tự giảm dần và nhận mục đầu tiên:

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

4
Tôi cho rằng bạn cũng có thể sắp xếp và lấy món đồ cuối cùng ...?
Shog9

@ Shog9: Có, nhưng bạn sẽ cần tự mình chỉ định chức năng so sánh:sort(function(a,b){return b-a;})
Gumbo

9
Ah. Tôi đã suy nghĩ nhiều hơn như:[...].sort().pop()
Shog9

4
"việc tìm số mất thứ tự-n, sắp xếp mất giữa thứ tự (n log n) để đặt hàng (n bình phương), phụ thuộc vào thuật toán sắp xếp được sử dụng" - webmasterworld.com/forum91/382.htmlm
Marco Luglio

2
Cũng nên nhớ rằng điều này sắp xếp các mảng, có thể hoặc không thể là một tác dụng phụ mong muốn. Các giải pháp áp dụng là hiệu suất tốt hơn và không có tác dụng phụ.
Caleb

28

Còn cái này thì sao:

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

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

console.log(largest);

Nếu tôi thấy câu trả lời này đầu tiên (hiện ở cuối danh sách) tôi sẽ lưu được hai giờ.
user139602

1
Cách tiếp cận Math.max có lẽ là tiêu chuẩn nhất, nhưng tôi đã bị tràn ngăn xếp khi mảng quá lớn (500K). Câu trả lời này nhanh và hiệu quả và là câu trả lời cuối cùng tôi sử dụng, vì vậy tôi ủng hộ câu trả lời này.
Jay

8

Làm thế nào về việc sử dụng Array.reduce ?

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

Giá trị ban đầu nên được đặt thành -Infinity.
Ja͢ck

@Jack, tại sao điều này lại cần thiết? thậm chí với một mảng gồm tất cả các số âm, tôi nhận được kết quả hợp lệ.
CodeToad

1
Đó là trường hợp cạnh mà mảng trống.
Ja͢ck

5

Hầu như tất cả các câu trả lời sử dụng Math.max.apply()là tốt và đẹp nhưng có những hạn chế.

Các đối số chức năng được đặt trên ngăn xếp có nhược điểm - giới hạn. Vì vậy, nếu mảng của bạn lớn hơn giới hạn, nó sẽ thất bại vớiRangeError: Maximum call stack size exceeded.

Để tìm kích thước ngăn xếp cuộc gọi, tôi đã sử dụng mã này:

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;
  }
}

Nó được chứng minh là lớn nhất trên FireFox trên máy của tôi - 591519 . Điều này có nghĩa là nếu mảng của bạn chứa hơn 591519 mục, Math.max.apply()sẽ dẫn đến RangeError .

Giải pháp tốt nhất cho vấn đề này là cách lặp (tín dụng: 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];
}

Tôi đã viết về câu hỏi này trên blog của tôi ở đây .


1
Cái này không công bằng. Tôi muốn câu trả lời ngay tại đây, trên SO, không phải liên kết khác đến tài nguyên của bên thứ ba khác. Đặc biệt là khi nó kết hợp với "mọi thứ ở đây đều tệ, nhưng hãy nhìn xem, nó thật tuyệt vời trên blog của tôi ..."
osa

@SergeyOrshanskiy một liên kết đến bên thứ ba hoạt động rất tốt trong trường hợp nó được cập nhật với các giải pháp và giải pháp mới. Cũng không cần phải cảm thấy bị xúc phạm. Mọi người chỉ muốn giải quyết vấn đề của bạn quá. Tôi cũng muốn giải quyết nó, vì vậy tôi đã viết về nó trên blog của mình
lukas.pukenis

5

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);


2
Tuy nhiên, cả lây lan (...) và áp dụng sẽ thất bại hoặc trả về kết quả sai nếu mảng có quá nhiều phần tử developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ tựa
Green

5

Tìm giá trị tối đa và tối thiểu một cách dễ dàng và thủ công. Mã này nhanh hơn nhiều Math.max.apply; Tôi đã thử tới 1000k số trong mảng.

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()cho kết quả sai nếu chỉ có số âm trong mảng; findmin()đưa ra kết quả sai cho một mảng trống.
Ja͢ck




1

Đừng quên rằng gói có thể được thực hiện với Function.prototype.bind, cung cấp cho bạn một chức năng "tất cả bản địa" .

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

1

Bạn cũng có thể mở rộng Arrayđể có chức năng này và biến nó thành một phần của mỗi mảng.

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

console.log( myArray.max() );

1
Không hiệu quả khủng khiếp.
Frank Schmitt

@FrankSchmitt, cảm ơn bạn, tôi đồng ý. Câu trả lời ban đầu không phải là một giải pháp tốt. Sắp xếp theo mặc định không sắp xếp số, nó coi các phần tử là chuỗi. Chỉnh sửa câu trả lời của tôi để có đúng loại.
Izz

Đó không phải là quan điểm của tôi. Sắp xếp một mảng để tìm mức tối đa là không hiệu quả, vì nó cần ít nhất N hoạt động N log, trong khi việc tìm tối đa có thể được thực hiện trong N hoạt động.
Frank Schmitt

1

Bạn cũng có thể sử dụng 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


1

Sử dụng - Array.prototype.reduce()thật tuyệt!

[267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val)

trong đó acc = ắc quyval = giá trị hiện tại ;

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

console.log(a);


1

Bạn có thể thử điều này,

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);

1

Tôi mới bắt đầu với JS nhưng tôi nghĩ phương pháp này sẽ tốt:

var array = [34, 23, 57, 983, 198];<br>
var score = 0;

for(var i = 0; i = array.length; i++) {
  if(array[ i ] > score) {
    score = array[i];
  }
}

Điều này sẽ gặp rắc rối nếu arraychỉ chứa số âm.
Teepeemm

0

Tìm số lớn nhất trong một mảng nhiều chiều

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;

Luôn luôn nên thêm một số giải thích chi tiết vào mã của bạn, đặc biệt nếu đã có nhiều câu trả lời khác. Tại sao điều này khác / tốt hơn?
Bowdzone

@Bowdzone, cảm ơn vì nhận xét. cách này rất cơ bản, điều khiến nó trở nên đơn giản dễ hiểu với một chút kiến ​​thức về chỉ một vài phương pháp.
Liveindream

Điều này không trả về số lớn nhất, nó trả về một mảng có số lượng lớn nhất của mỗi mảng trong mảng nhiều chiều. Bạn sẽ cần phải thêm ví dụ var tmax = Math.max.apply(Math, max), hoặc tốt hơn nữa, sử dụng hàm đóng vòng lặp, ví dụ như trong stackoverflow.com/a/54980012/7438857 . Với sửa đổi này, câu trả lời tốt hơn cho một câu hỏi riêng biệt, làm thế nào để bạn "tìm số lớn nhất trong một mảng nhiều chiều", hoặc tại stackoverflow.com/questions/32616910/ . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
James Ray

stackoverflow.com/a/32617019/7438857 là câu trả lời tốt hơn cho câu hỏi đúng, trong khi câu trả lời này không trả lời câu hỏi trên, nó trả về số lớn nhất trong mỗi mảng trong một mảng nhiều chiều.
James Ray

0

Chạy cái này:

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

Và bây giờ hãy thử [3,10,2].max()trả lại10


0

Tìm giá trị Max và Min bằng cách sử dụng Bubble Sort

    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
(1) Mảng Javascript đã có chức năng sắp xếp O (n log n). (2) Sắp xếp bong bóng là O (n ^ 2). (3) Tìm min và max là O (n).
Teepeemm

0

Thử cái này

function largestNum(arr) {
  var currentLongest = arr[0]

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

  return currentLongest
}

1
Là câu trả lời này về cơ bản khác với nhiều người khác trên trang này?
Teepeemm

0

Theo nhận xét của @ Quasimondo , dường như đã bị bỏ lỡ phần lớn, bên dưới dường như có hiệu suất tốt nhất như được hiển thị ở đây: https://jsperf.com/finding-maximum-element-in-an-array . Lưu ý rằng trong khi đối với mảng trong câu hỏi, hiệu suất có thể không có ảnh hưởng đáng kể, đối với hiệu suất mảng lớn trở nên quan trọng hơn và một lần nữa như đã lưu ý khi sử dụng Math.max()thậm chí không hoạt động nếu độ dài mảng lớn hơn 65535. Xem thêm câu trả lời này .

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;
}

0

Một cách tiếp cận đệ quy về cách thực hiện bằng cách sử dụng các toán tử ternary

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);


0

for/ofGiải pháp một vòng lặp:

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);

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.