JavaScript配列に含まれる最大の数を見つけるにはどうすればよいですか?


206

いくつかの数値を含む単純なJavaScript配列オブジェクトがあります。

[267, 306, 108]

この配列で最大の数を見つける関数はありますか?


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

回答:


315

救助に立ち向かう:

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

警告一部のVMでは引数の最大数が65535と少ないため、配列がそれほど小さいことが確実でない場合はforループを使用します


15
ああ、でも今は少し品質の悪い方法でSOの品質ステッカーが貼られています!
Shog9 2009

2
FWIW、パフォーマンスがソリューションの要因である場合は、簡単にコーディングできる独自の関数と比較してテストし、適切に機能することを確認します。ネイティブ実装の方が速いと思いがちです。実際、apply通話料金はそれを簡単に洗い流してしまいます。
TJクラウダー

2
配列の長さがパラメーター数の制限よりも大きい場合はどうなりますか?
lukas.pukenis 2013年

3
これによると@CrescentFresh:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…これは65535にハードコードされています。これによれば:code.google.com/p/v8/issues/detail?id = 172そして引数がスタックにプッシュされるという知識により、それが無制限ではないことがわかります
lukas.pukenis

9
また、この方法は堅牢ではありません。配列がmamximumスタックサイズよりも大きい場合、失敗します。その結果RangeError: Maximum call stack size exceeded.
Mark Lundin

197

apply関数を使用して、Math.maxを呼び出すことができます。

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

使い方?

適用関数は、アレイとして提供所与のコンテキストと引数と、別の関数を呼び出すために使用されます。min関数とmax関数は、任意の数の入力引数を取ることができます:Math.max(val1、val2、...、valN)

だから私たちが呼び出す場合:

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

適用関数が実行されます。

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

最初のパラメーターであるコンテキストは静的なので、これらの関数にとって重要ではありません。これらはコンテキストとして渡されるものに関係なく機能します。


2
おっと

1
それは素晴らしいことです。しかし、配列の長さが(関数の)パラメータサイズの制限を超えた場合はどうなりますか?じゃあ?
lukas.pukenis 2013年

1
すべての機能とその理由が説明されているので、他の回答よりもこの回答が好きです。+1
Marvin

59

新しいスプレッド演算子を使用した最も簡単な構文:

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

出典:Mozilla MDN


2
しかし、両方のスプレッド(...)と、失敗したり、配列があまりにも多くの要素を持っている場合、誤った結果を返しますいずれかの適用 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
グリーン

@Green FWIW、パラメーター数の制限は65536(少なくともChromeでは)([source(bugs.webkit.org/show_bug.cgi?id=80797)])です。したがって、配列に65536を超える要素がある場合、この答えは機能しません。
mgthomas99

4
65536は誰にとっても十分なはずです
vsync 2018

41

私はJSの専門家ではありませんが、これらのメソッドがどのように積み重なっていくのかを見たかったので、これは私にとって良い習慣でした。これが技術的にこれらをパフォーマンステストするための正しい方法であるかどうかはわかりませんが、コードで確認できるように、次々に実行しました。

0番目の値の並べ替えと取得は、最悪の方法です(配列の順序が変更されるため、望ましくない場合があります)。他の人にとっては、何百万ものインデックスを話しているのでない限り、違いは無視できます。

乱数の100,000インデックス配列での5回の実行の平均結果:

  • 削減の実行には4.0392ミリ秒かかりました
  • Math.max.applyの実行に3.3742msかかりまし
  • 0番目の値を並べ替えて取得するのに67.4724msかかりました
  • 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)

7
私にとって、これはこの質問に対する最良の答えです。
rzelek

1
私はjsperf tests上記のために作成しました
vsync 2018

37

より大きな配列(約10万個の要素)の場合、実際には単純なforループで配列を反復処理するだけで十分であり、以下よりも約30%高いパフォーマンスが得られ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;
}

ベンチマーク結果


3
FWIW、クロム31に今84%に出てくる
宜蘭ビャワ

31

配列を降順で並べ替えて、最初の項目を取得できます。

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

4
最後のアイテムを並べ替えて取得することもできると思います...?
Shog9 2009

@ Shog9:はい、ただし自分で比較関数を指定する必要があります:sort(function(a,b){return b-a;})
Gumbo

9
ああ。私は次のように考えていました:[...].sort().pop()
Shog9

4
- 「番号を見つけることが使用されるソートアルゴリズムにdependig、順序-N、ソートの順序(N乗)に(N Nログ)ためかかりかかる」webmasterworld.com/forum91/382.htm
マルコLuglio

2
また、これは配列をソートすることにも注意してください。これは望ましい副作用である場合とそうでない場合があります。適用ソリューションはパフォーマンスが高く、副作用はありません。
カレブ2013年

28

これはどう:

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

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

console.log(largest);

この答えを最初に見た場合(現在はリストの一番下)、2時間節約できたでしょう。
user139301

1
Math.maxアプローチはおそらく最も標準的ですが、配列が大きすぎる(500K)とスタックオーバーフローが発生しました。この答えは速くて効率的であり、私が自分自身を使用することになったので、これを賛成します。
ジェイ

8

どのように使用する方法についてArray.reduceを

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

初期値はに設定する必要があります-Infinity
JACK

@ジャック、なぜこれが必要なのですか?すべての負の数の配列を使用しても、有効な結果が得られます。
CodeToad 2014

1
これは、配列が空になるエッジケースです。
ジャック

5

回答のほとんどすべてが使用して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];
}

私はこの質問についてここの私のブログに書い


1
これは公平ではない。私はここで答えを求めています。SOでは、別のサードパーティリソースへの別のリンクではありません。特に、「ここにあるものすべてが悪いですが、見てください、私のブログではとても素晴らしいです」と組み合わせると
osa

@SergeyOrshanskiyサードパーティへのリンクは、新しい情報やソリューションで更新された場合に非常にうまく機能します。また、気分を害する必要はありません。人々もあなたの問題を解決したいだけです。私もそれを解決したかったので、ブログに書いた
lukas.pukenis 2013年

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
しかし、両方のスプレッド(...)と、失敗したり、配列があまりにも多くの要素を持っている場合、誤った結果を返しますいずれかの適用 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
グリーン

5

最大値と最小値を見つけることは、簡単で手動の方法です。このコードは、よりもはるかに高速です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()空の配列に対して誤った結果を与えます。
ジャック・


3

はい、もちろん存在します:Math.max.apply(null,[23,45,67,-45]) そして結果が返され67ます。



1

ラップはで行うことがFunction.prototype.bindでき、「すべてネイティブ」の機能を提供することを忘れないでください。

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

1

Arrayこの関数を追加して、すべての配列の一部にすることもできます。

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

console.log( myArray.max() );

1
ひどく非効率的です。
フランクシュミット2014

@FrankSchmitt、ありがとう、同意します。元の答えは良い解決策ではありませんでした。デフォルトで並べ替えは数値を並べ替えません。要素を文字列として扱います。正しい並べ替えができるように私の回答を編集しました。
Izz

それは私の趣旨ではありませんでした。配列をソートして最大値を見つけることは、それが少なくともN log Nの操作を必要とするので、それ自体は非効率的です。
フランクシュミット


1

使い方Array.prototype.reduce()はかっこいい!

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

ここで、acc =アキュムレータval =現在の値です。

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

console.log(a);


1

これを試すことができます

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

私はJSを始めたばかりですが、この方法が良いと思います:

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

array負の数しか含まれていない場合、これは問題になります。
Teepeemm 2018

0

多次元配列で最大の数を見つける

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、2015

@Bowdzone、コメントありがとう。この方法は非常に基本的なものであり、ほんの少しの方法について少しの知識があれば簡単に理解できます。
Liveindream 2015

これは最大数を返すのではなく、多次元配列内の各配列の最大数の配列を返します。たとえばvar tmax = Math.max.apply(Math, max)、追加する必要があります。さらに良いのは、たとえばstackoverflow.com/a/54980012/7438857のループ関数のクロージャーを使用することです。この変更により、別の質問、「多次元配列の最大数を見つける方法」、またはstackoverflow.com/questions/32616910/…でより適切に回答されます。WIP:jsfiddle.net/jamesray/3cLu9for/8
ジェームズレイ

stackoverflow.com/a/32617019/7438857は正しい質問に対するより良い回答ですが、この回答は上記の質問には答えませんが、多次元配列内の各配列の最大数を返します。
James Ray

0

これを実行してください:

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

そして今度[3,10,2].max()はリターンを試みなさい10


0

バブルソートを使用して最大値と最小値を見つける

    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)Javascript配列にはすでにO(n log n)ソート関数があります。(2)バブルソートはO(n ^ 2)です。(3)最小値と最大値を見つけることはO(n)です。
Teepeemm 2018

0

これを試して

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
この回答は、このページの他の多くの回答と大幅に異なりますか?
Teepeemm 2018

0

@Quasimondoの コメントによると、これはほとんど見落とされているようですが、以下に示すように、以下が最高のパフォーマンスを発揮するようです:https : //jsperf.com/finding-maximum-element-in-an-array。注問題の配列のため、パフォーマンスが大きな影響を持っていないかもしれないが、大きな配列のためにパフォーマンスがより重要な、そして再びなることとして指摘使ってMath.max()配列の長さにもより65535を参照の場合はしないのも、仕事をこの答え

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

三項演算子を使用してそれを行う方法に関する再帰的アプローチ

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

1つの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);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.