JavaScriptで配列の最小/最大要素を見つける


779

JavaScript配列の最小要素または最大要素を簡単に取得するにはどうすればよいですか?

擬似コードの例:

let array = [100, 0, 50]

array.min() //=> 0
array.max() //=> 100

93
注: ECMAScriptの6を使用すると、新しい使用することができますスプレッド演算子:(3個のドット...で)Math.max()このように:Math.max(...[2, 5, 16, 1])MDNドキュメントからの私の回答を参照しください。
totymedli 2015年

1
回答を承認済みとしてマークすることを検討してください。
Alex

これを行う最も一般的な方法の速度比較のベンチマーク:jsben.ch
#

es6は基本的に素晴らしいです!:)
datdinhquoc

ES6なし Math.max.apply(null, [2,5,16,1])
Tomer

回答:


828

代わりにMath.max/ を使用するように組み込みのArrayオブジェクトを拡張するのはどうですか?Math.min

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

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

こちらがJSFiddleです。

ビルトインを増強することは、他のライブラリ(一部参照)との衝突を引き起こす可能性がありますので、あなただけでより快適かもしれapply「INGのMath.xxx()直接配列へ:

var min = Math.min.apply(null, arr),
    max = Math.max.apply(null, arr);

または、ブラウザーがECMAScript 6をサポートしていると仮定すると、メソッドと同様に機能するスプレッド演算子を使用できますapply

var min = Math.min( ...arr ),
    max = Math.max( ...arr );

8
@HankH:合格nullまたはMathまたは{}または何にapply()call()な結果とは関係ありません。内部でMath.max参照することも、参照することもできませんthis
Roatin Marth

31
C#プログラマーとして、強く型付けされた質問が必要です。
ChaosPandion 2009年

7
上記のコードで行ったjQueryの間違いを共有するだけで、デバッグに長い時間がかかりました。jquery配列は、iPad以外のすべてで正常に動作します。それを機能させるには、配列を真のネイティブ配列に変換する必要がありました。何らかの理由で単一のデバイスのみに影響を与えたMath.max.apply(null, $.makeArray(array));
Forrest

11
提案されたアプローチはスタックフレームでO(n)メモリを消費し、結果として大きな配列でクラッシュするため、私は反対票を投じました。私の場合、nodejsをクラッシュさせるには、約130000の数値で十分でした。
Alexey Timanovsky、2015

14
このような組み込みのプロトタイプを増強しないでください。他のライブラリとの競合だけではありません。また、ブラウザ自体が将来的に、.maxまたは.minメソッドを提供する可能性についてもです。完全に現実的なシナリオ:この答えを使用します。2016年に、ES7またはES8スペックArray.maxArray.min。このバージョンとは異なり、文字列で動作します。あなたの将来の同僚は、文書化されたネイティブ.max()メソッドを使用して、アルファベット順で最新の文字列を配列で取得しようとしますが、不思議なことにを取得しNaNます。数時間後、彼女はこのコードを見つけ、を実行しgit blame、あなたの名前を呪います。
Mark Amery 2015

362
var max_of_array = Math.max.apply(Math, array);

詳細については、http//aaroncrane.co.uk/2008/11/javascript_max_api/を参照して ください。


13
違いは何であるMath.max.apply(Math, array)とはMath.max.apply(null, array)?ブログには「...にmax属するものについても、冗長にもう一度言う必要がある」とありますMathが、そうする必要はないようです(最初の引数をapplyasに設定することによりnull)。
ziyuang

9
@ziyuangをのようMath.max(a,b)に呼び出すとMaththis値として渡されるため、で呼び出すときに同じようにすると意味がある場合がありapplyます。ただしMath.maxthis値は使用しないため、任意の値を渡すことができます。
Oriol

199

大きな配列(〜10⁷要素)の場合Math.minMath.max両方ともNode.jsで次のエラーを生成します。

RangeError:呼び出しスタックの最大サイズを超えました

より堅牢なソリューションは、すべての要素を呼び出しスタックに追加するのではなく、配列を渡すことです。

function arrayMin(arr) {
  return arr.reduce(function (p, v) {
    return ( p < v ? p : v );
  });
}

function arrayMax(arr) {
  return arr.reduce(function (p, v) {
    return ( p > v ? p : v );
  });
}

速度が気になる場合は、次のコードの方Math.max.applyが私のコンピューターにある場合よりも3倍高速です。http://jsperf.com/min-and-max-in-array/2を参照してください。

function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (arr[len] < min) {
      min = arr[len];
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (arr[len] > max) {
      max = arr[len];
    }
  }
  return max;
};

配列に数値ではなく文字列が含まれている場合は、それらを数値に強制変換する必要もあります。以下のコードはそれを行いますが、私のマシンではコードを約10倍遅くします。http://jsperf.com/min-and-max-in-array/3を参照してください。

function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (Number(arr[len]) < min) {
      min = Number(arr[len]);
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (Number(arr[len]) > max) {
      max = Number(arr[len]);
    }
  }
  return max;
};

割り当てminmax最後の要素へと1回の反復を減らす(while(--len));)
Venugopal

@Venugopalの場合、配列が空であるかどうかを確認するための特別なチェックが必要で、+ /
-Infinity

2
奇妙なことに...リンク先のWebサイトにアクセスしました...そしてFirefox 51.0.0 / Mac OS X 10.12.0でテストすると、縮小ベースのアプローチはループベースよりも30%遅くなります...非常に異なる結果
Pierpaolo Cira

2
very different results あなたは)この5年後でした
АлексейЛещук

1
2019年reduceソリューションは最も遅いです。数百万の要素を持つ配列を扱う場合でも、標準のforループを使用することをお勧めします詳細については私の答えを参照してください。
totymedli

152

スプレッド演算子(ES6)の使用

Math.max(...array);  // the same with "min" => Math.min(...array);


8
このソリューションは、他の複数 回答によってすでに提供されます。
totymedli 2017

15
Math.max(... [])=-無限。ハハハ😂😂😂–
デビッド

@DavidPortabellaなぜそれが面白いのかわからない。それは、それがどのように動作するかだ仕様に応じてIf no arguments are given, the result is -∞.
パトリック・ロバーツ

3
はい、私はjavascript仕様が恐ろしいことを意味しました。数字の最小値が計算できないことは明らかです。Scalaなどの他のより深刻なプログラミング言語では、空の配列のminを要求すると例外がスローされます。
デビッドPortabella

3
Scalaは、それが間違っていることを伝えるためにマシンが必要な人のためのものです
thedanotto

106

tl; dr

// For regular arrays:
var max = Math.max(...arrayOfNumbers);

// For arrays with tens of thousands of items:
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
  if (testArray[i] > max) {
    max = testArray[i];
  }
}

MDNソリューション

公式MDNドキュメントはMath.max()すでにこの問題をカバーています:

次の関数は、Function.prototype.apply()を使用して、数値配列の最大要素を検索します。getMaxOfArray([1, 2, 3])はと同等Math.max(1, 2, 3)ですがgetMaxOfArray()、プログラムで作成された任意のサイズの配列で使用できます。

function getMaxOfArray(numArray) {
    return Math.max.apply(null, numArray);
}

または、新しいスプレッド演算子を使用すると、配列の最大値を取得するのがはるかに簡単になります。

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

配列の最大サイズ

MDNによると、展開applyソリューションに 65536の制限があり、これは引数の最大数の制限によるものです。

ただし、注意してください。applythis wayを使用すると、JavaScriptエンジンの引数の長さ制限を超えるリスクがあります。引数が多すぎる(数万を超えると考える)関数を適用した場合の結果は、エンジンによって異なります(JavaScriptCoreには65536の引数がハードコードされています)。動作)は指定されていません。一部のエンジンは例外をスローします。さらに悪質なことに、適用された関数に実際に渡される引数の数を制限する人もいます。この後者のケースを説明すると、そのようなエンジンに4つの引数の制限があった場合(実際の制限はもちろん大幅に高くなります)、上記の例に適用するために引数5、6、2、3が渡されたかのようになります。完全な配列ではなく。

彼らは、他のソリューションと比較して実際に優れたパフォーマンスを持たないハイブリッドソリューションさえ提供します。詳細については、以下のパフォーマンステストを参照してください。

2019年の実際の制限は、コールスタックの最大サイズです。最新のChromiumベースのデスクトップブラウザーの場合、これは、最小値applyまたは最大値またはスプレッドを検出する場合、実際には数値のみの配列の最大サイズが〜120000であることを意味します。これを超えると、スタックオーバーフローが発生し、次のエラーがスローされます。

RangeError:呼び出しスタックの最大サイズを超えました

以下のスクリプト(このブログ投稿に基づく)では、そのエラーをキャッチすることで、特定の環境の制限を計算できます。

警告!このスクリプトの実行には時間がかかり、システムのパフォーマンスによっては、ブラウザー/システムが遅くなったりクラッシュしたりする場合があります。

let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));
for (i = 10000; i < 1000000; ++i) {
  testArray.push(Math.floor(Math.random() * 2000000));
  try {
    Math.max.apply(null, testArray);
  } catch (e) {
    console.log(i);
    break;
  }
}

大規模アレイでのパフォーマンス

EscapeNetscapeのコメントのテストに基づいて、100,000アイテムの乱数のみの配列で 5つの異なるメソッドをテストするいくつかのベンチマークを作成しました。

2019年の結果は、標準ループ(BTWにはサイズ制限がない)がどこでも最速であることを示しています。applyそして、その直後に拡散が続き、その後、MDNのハイブリッドソリューションreduceが最も遅くなります。

ほとんどすべてのテストで同じ結果が得られました。

配列を100万個のアイテムにステップアップすると、状況が崩れ始め、標準ループは高速なソリューションとreduce低速なソリューションとして残されます。

JSPerfベンチマーク

配列の最小/最大アイテムを見つけるためのさまざまなソリューションのjsperf.comベンチマーク結果

JSBenベンチマーク

配列の最小/最大項目を見つけるためのさまざまなソリューションのjsben.comベンチマーク結果

JSBench.meベンチマーク

配列の最小/最大アイテムを見つけるためのさまざまなソリューションのjsbench.meベンチマーク結果

ベンチマークソースコード


typescriptを使用している場合、示されているスプレッド演算子はMath.max.apply(Math, arr)「最大」の互換性のためにコンパイルされます。
Simon_Weaver 2018

1
また、MDNから:「両方の広がり(...)apply失敗したり、配列があまりにも多くの要素を持っている場合、誤った結果を返しますいずれかの[...]このような問題はありませんソリューションを減らす」のテストChromeを、FF、エッジとIE11はあると思われます100kまでの値の配列には問題ありません。(Win10および最新のブラウザーでテスト済み:Chrome 110k、Firefox 300k、Edge 400k、IE11 150k)。
oriadam

これは非常に遅い方法ですが、配列に数千の要素がある場合はどうなりますか?
Slava Fomin II

@SlavaFominII答えを拡張して、何千もの要素を含む配列をカバーしました。
totymedli

68

私のように使用することに偏執的である場合Math.max.applyMDNに従って大きな配列を指定するとエラーが発生する可能性があります)、これを試してください:

function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.max(a, b);
  });
}

function arrayMin(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  });
}

または、ES6では:

function arrayMax(array) {
  return array.reduce((a, b) => Math.max(a, b));
}

function arrayMin(array) {
  return array.reduce((a, b) => Math.min(a, b));
}

無名関数は、残念ながら必要に応じて(代わりに使用しているMath.max.bind(Math)ので、reduceただ合格しないaと、bその機能にするだけでなく、i我々は呼び出すためにしようとしないことを確認する必要がありますので、配列自体への参照maxだけでなく、それらに。


あなたのES6の例では、単に戻るだけではない理由がありますMath.max(...array)か?
Wojciech Bednarski

@WojciechBednarski このページは、spread演算子の使用は配列をapplyに渡すことと同じであるため、同じ欠点(最大引数制限)があることを示唆しているようです。
Daniel Buckmaster 2016

これをありがとう。削減後に欠落しているブラケットを修正することができます:function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Arkowsky

1
@DanielDietrich私は同等のことをしていると思いMath.min()ますInfinity、値なしで呼び出すと、が返されるので、これらの関数はreduce(..., Infinity)その動作に一致させるために使用できます。ただし、(現在のように)例外をスローすることをお勧めします。空の配列を最小限にするとエラーになる可能性があるためです。
ダニエル・バックマスター

1
これまでのところ、reduceが最も遅いです。
АлексейЛещук

40

.apply 引数値のリストを使用して可変個関数を呼び出すことが目的の場合によく使用されます。例:

このMath.max([value1[,value2, ...]])関数は、ゼロまたはそれ以上の数値の最大値を返します。

Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

このMath.max()メソッドでは、配列を渡すことはできません。最大値を取得する必要がある値のリストがある場合、通常はFunction.prototype.apply()を使用してこの関数を呼び出します。たとえば、

Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20

ただし、ECMAScript 6以降では、spread演算子を使用できます。

スプレッド演算子を使用すると、複数の引数(関数呼び出しの場合)または複数の要素(配列リテラルの場合)が予想される場所で式を展開できます。

スプレッド演算子を使用すると、上記のように書き直すことができます。

Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20

可変個の演算子を使用して関数を呼び出すときは、さらに値を追加することもできます。

Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50

ボーナス:

スプレッド演算子は、あなたはES5にあなたがの組み合わせを使用して、必要不可欠コードにフォールバックする必要があるだろう状況で新しいアレイを作成するには、配列リテラル構文を使用することを可能にするpushspliceなど、

let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']

1
ボーナスの最後の例は、concat単一の線スタイルを維持できるため、ほとんどのプログラマーが使用して記述します。
コーディアランテイラー

31

2つの方法は短くて簡単です。

let arr = [2, 6, 1, 0]

方法1

let max = Math.max.apply(null, arr)

方法2

let max = arr.reduce(function(a, b) {
    return Math.max(a, b);
});

配列が空である場合は注意してください。負の無限大になるので、必要としない場合があります。取得し0たい場合は[0].concat(arr)、スプレッド構文[0, ...arr]( 'arr'の代わりに)を使用できます
Simon_Weaver

方法1でnull値を除外する方法はありますか?
bonbon.langes

22

これを行うには、Arrayタイプを拡張します。

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

ここから後押し(John Resigによる)


20

Array要素の最小値を見つける簡単な解決策は、Arrayプロトタイプ関数を使用することreduceです:

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9

またはJavaScriptの組み込みMath.Min()関数を使用(@Tenflexに感謝):

A.reduce((min,val) => Math.min(min,val), A[0]);

これはに設定さminA[0]A[1]...A[n]現在の値よりも厳密に小さいかどうかを確認しminます。場合はA[i] < min、その後minに更新されますA[i]。すべての配列要素が処理されるminと、結果として返されます。

編集:最小値の位置を含める:

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }

3
A.reduce((min、val)=> Math.min(min、val)、A [0]); さらに短い
Tenflex

おまけの質問として、min値を返すだけでなく、配列内での位置を返す方法はありますか?
-stevek

@meshfields-答えを更新しました。
Nicolas Lykke Iversen

15

他の人たちは、それらを増強するいくつかの解決策をすでに与えていArray.prototypeます。私はこの答えに欲しいのは、それがどうあるべきかを明らかにすることですMath.min.apply( Math, array )Math.min.apply( null, array )だから何コンテキストを使用し、する必要がありますMathnull

nullコンテキストとして渡すとapply、コンテキストはデフォルトでグローバルオブジェクト(windowブラウザの場合はオブジェクト)になります。Mathオブジェクトをコンテキストとして渡すことは正しい解決策ですが、渡すことも害にはなりませんnull。関数をnull装飾するときに問題が発生する可能性がある場合の例を次に示しMath.maxます。

// decorate Math.max
(function (oldMax) {
    Math.max = function () {
        this.foo(); // call Math.foo, or at least that's what we want

        return oldMax.apply(this, arguments);
    };
})(Math.max);

Math.foo = function () {
    print("foo");
};

Array.prototype.max = function() {
  return Math.max.apply(null, this); // <-- passing null as the context
};

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

print(max);

ため、上記の例外がスローされますthis.fooように評価されるwindow.fooです、undefined。で置き換えるnullMath、期待どおりに動作し、文字列「foo」が画面に表示されます(これはMozilla Rhinoを使用してテストしました)。

だれもMath.maxそのように装飾していないとほぼ仮定できnullます。パスは問題なく機能します。


2
ポイントを取る。しかし、なぜ誰かが装飾Foo.staticMethodして参照するのthisですか?それはデコレータのデザインの間違いではないでしょうか?(もちろん、しない限り、彼らがして望むグローバルスコープを参照するように、としたい使用されているJavaScriptエンジンの独立性を維持するために、例えばサイ)。
Roatin Marth

1
仕様は、どの仕様関数が「the this value」を参照する必要があるかについて明示的です(実際、その句は仕様で125回出現します)。Math.max、仕様に従って実装され、は使用しませんthis。誰かMath.maxがを使用するようにオーバーライドした場合this、その動作は仕様に違反しているため、鋭いオブジェクトを投げる必要があります。その可能性をコーディングするのは、誰かが入れ替えた可能性Math.maxMath.minlulzをコーディングするのと同じです。
Mark Amery、2015

15

それを行うもう1つの方法:

var arrayMax = Function.prototype.apply.bind(Math.max, null);

使用法:

var max = arrayMax([2, 5, 1]);

誰かがこれがどのように機能するか説明できますか?これはかなりドープです。私の理解は正しいですか:arrayMaxは関数であり、そのプロトタイプのプロパティに何かをバインドしますか?これはapply.bindとは何ですか?すべてのプロトタイプにはありますか?
サム


14

代替方法


メソッドJSエンジンのコールスタックに追加されていることの両方の再帰的な操作であり、最も可能性の高いクラッシュのアイテムが多数含まれているアレイ用(〜10⁷項目以上に、ユーザーのブラウザに依存します)。Math.minMath.max

Math.max(... Array(1000000).keys());

キャッチされないRangeError:呼び出しスタックの最大サイズを超えました

代わりに、次のようなものを使用します。

arr.reduce((max, val) => max > val ? max : val, arr[0])

または、より良いランタイムで:

function maxValue(arr) {
  let max = arr[0];

  for (let val of arr) {
    if (val > max) {
      max = val;
    }
  }
  return max;
}

または、最小と最大の両方を取得するには:

function getMinMax(arr) {
  return arr.reduce(({min, max}, v) => ({
    min: min < v ? min : v,
    max: max > v ? max : v,
  }), { min: arr[0], max: arr[0] });
}

または、さらに優れたランタイム*:

function getMinMax(arr) {
  let min = arr[0];
  let max = arr[0];
  let i = arr.length;

  while (i--) {
    min = arr[i] < min ? arr[i] : min;
    max = arr[i] > max ? arr[i] : max;
  }
  return { min, max };
}

* 1,000,000項目でテスト:
参考までに、(私のマシンでの)1番目の関数の実行時間は15.84ミリ秒でしたが、4.32ミリ秒で2番目の関数が実行されました。


13

これはあなたの目的に合うかもしれません。

Array.prototype.min = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.min);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

Array.prototype.max = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.max);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

0より小さい番号がない場合は、vを 'this [0]'で初期化する必要があります
jasonmw

されたcomparerいくつかの特定のスコープで呼び出されることになって?それが参照されているためthis[index]であるundefined毎回。
Roatin Marth

修正済み、関数レベルのスコープについては常に忘れます。
ChaosPandion 2009年

ああ、今、@ Ionut G. Stanは、デフォルトの比較Math.xxx
演算子

それは本当かもしれませんが、新しい関数シグネチャは、比較する必要がある2つのオブジェクトを取得するため、スコープを必要としません。
ChaosPandion 2009年


12

リデュース機能について触れられていないことに驚いています。

var arr = [1, 10, 5, 11, 2]

var b = arr.reduce(function(previous,current){ 
                      return previous > current ? previous:current
                   });

b => 11
arr => [1, 10, 5, 11, 2]

注意:reduce()はIE9からサポートされています
。developer.mozilla.org/ en

1
現在のバージョンのChromiumではこれを使用できないようです。
PJSCopeland 2014

9

大きな配列(〜10⁷ 要素)の場合Math.minMath.maxnode.jsでRangeError(最大コールスタックサイズを超えた)が発生します。

大規模なアレイの場合、すばやく簡単なソリューションは次のとおりです。

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

8

同じ問題がありました。配列の最小値と最大値を取得する必要があり、驚いたことに、配列の組み込み関数がありませんでした。たくさん読んだ後、「トップ3」のソリューションを自分でテストすることにしました。

  1. 個別のソリューション:現在の最大値および/または最小値に対して配列のすべての要素をチェックするFORループ。
  2. APPLYソリューション:apply(null、array);を使用して配列をMath.maxおよび/またはMath.min内部関数に送信します。
  3. REDUCEソリューション:reduce(function)を使用して、配列のすべての要素に対するチェックを再帰的に行います。

テストコードはこれでした:

function GetMaxDISCRETE(A)
{   var MaxX=A[0];

    for (var X=0;X<A.length;X++)
        if (MaxX<A[X])
            MaxX=A[X];

    return MaxX;
}

function GetMaxAPPLY(A)
{   return Math.max.apply(null,A);
}

function GetMaxREDUCE(A)
{   return A.reduce(function(p,c)
    {   return p>c?p:c;
    });
}

配列Aは100,000個のランダムな整数で埋められ、各関数はWindows Vista搭載のIntel Pentium 4 2.99GHzデスクトップ上のMozilla Firefox 28.0で10,000回実行されました。時間は秒単位で、performance.now()関数によって取得されます。結果は次のとおりで、3つの小数桁と標準偏差が含まれています。

  1. 離散解:平均= 0.161秒、sd = 0.078
  2. APPLYソリューション:平均= 3.571秒、sd = 0.487
  3. REDUCEソリューション:平均= 0.350秒、sd = 0.044

REDUCEソリューションは、個別ソリューションより117%遅くなりました。APPLYソリューションは、ディスクリートソリューションよりも劣っており、2,118%遅くなりました。その上、Peterが観察したように、それは大きな配列(約1,000,000要素を超える)では機能しません。

また、テストを完了するために、この拡張ディスクリートコードをテストしました。

var MaxX=A[0],MinX=A[0];

for (var X=0;X<A.length;X++)
{   if (MaxX<A[X])
        MaxX=A[X];
    if (MinX>A[X])
        MinX=A[X];
}

タイミング:平均= 0.218秒、sd = 0.094

したがって、単純な離散ソリューションより35%遅くなりますが、最大値と最小値の両方を一度に取得します(他のソリューションでは、取得に少なくとも2倍かかります)。OPが両方の値を必要とすると、個別のソリューションが最良の選択になります(最大値を計算するための関数と最小値を計算するための関数の2つの別々の関数としても、2番目に優れたREDUCEソリューションよりも優れています)。


8

プロジェクトの任意の場所で次の関数を使用できます。

function getMin(array){
    return Math.min.apply(Math,array);
}

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

そして、配列を渡す関数を呼び出すことができます:

var myArray = [1,2,3,4,5,6,7];
var maximo = getMax(myArray); //return the highest number

8

次のコードは私のために働きます:

var valueList = [10,4,17,9,3];
var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); });
var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });

7

何度も繰り返しながら、進行状況を追跡します。

var min = null;
var max = null;
for (var i = 0, len = arr.length; i < len; ++i)
{
    var elem = arr[i];
    if (min === null || min > elem) min = elem;
    if (max === null || max < elem) max = elem;
}
alert( "min = " + min + ", max = " + max );

配列に要素がない場合、これは最小値/最大値をnullのままにします。配列に要素がある場合、1つのパスで最小値と最大値を設定します。

range上記を使用する方法でArrayを拡張して、再利用を可能にし、読みやすさを向上させることもできます。http://jsfiddle.net/9C9fU/で動作するフィドルを参照してください

Array.prototype.range = function() {

    var min = null,
        max = null,
        i, len;

    for (i = 0, len = this.length; i < len; ++i)
    {
        var elem = this[i];
        if (min === null || min > elem) min = elem;
        if (max === null || max < elem) max = elem;
    }

    return { min: min, max: max }
};

使用されます

var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];

var range = arr.range();

console.log(range.min);
console.log(range.max);

@JordanDillonChapian同意しますが、これを拡張してrange、最小値と最大値の両方を同時にIMOに取得するための最良の方法である関数に拡張するのは簡単です。
tvanfosson 2014

6

シンプルでわかりやすい解決策を共有したいと思いました。

最小:

var arr = [3, 4, 12, 1, 0, 5];
var min = arr[0];
for (var k = 1; k < arr.length; k++) {
  if (arr[k] < min) {
    min = arr[k];
  }
}
console.log("Min is: " + min);

そして最大のために:

var arr = [3, 4, 12, 1, 0, 5];
var max = arr[0];
for (var k = 1; k < arr.length; k++) {
  if (arr[k] > max) {
    max = arr[k];
  }
}
console.log("Max is: " + max);



ありがとう。答えを変えた。
Ionut Necula

繰り返しはまだ間違っています(存在しないプロパティにアクセスしています)。
Bergi、2016年

何が問題なのか、私は何も問題はないと思います。例を挙げていただけますか?
Ionut Necula

1
それに応じて変更されました。私はあなたを正しく理解したと思います。
Ionut Necula

6

数学関数の最大値と最小値を使用する以外に、使用するもう1つの関数は、sort()の組み込み関数です。

const nums = [12, 67, 58, 30].sort((x, y) => 
x -  y)
let max = nums[0]
let min = nums[nums.length -1]

5

本当に簡単なものです。

var arr = [10,20,30,40];
arr.max = function() { return  Math.max.apply(Math, this); }; //attach max funct
arr.min = function() { return  Math.min.apply(Math, this); }; //attach min funct

alert("min: " + arr.min() + " max: " + arr.max());

5

オブジェクトの配列から最大値を取得する1つの方法を次に示します。コピーを(スライス付きで)作成し、コピーを降順で並べ替え、最初のアイテムを取得します。

var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]

maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID; 

5

Math.max()またはを使用するMath.min()

Math.max(10, 20);   //  20
Math.min(-10, -20); // -20

次の関数はFunction.prototype.apply()、数値配列の最大要素を見つけるために使用します。getMaxOfArray([1, 2, 3])はと同等Math.max(1, 2, 3)ですがgetMaxOfArray()、プログラムで作成された任意のサイズの配列で使用できます。

function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}

または、新しいスプレッド演算子を使用すると、配列の最大値を取得するのがはるかに簡単になります。

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

4

ChaosPandionのソリューションは、プロトタイプを使用している場合に機能します。そうでない場合は、これを考慮してください:

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

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

上記は配列値が整数でない場合NaNを返すので、それを回避するためにいくつかの機能を構築する必要があります。それ以外の場合はこれでうまくいきます。


jeerose、Roatin Marthが(null、this)しか持っていないのに、どうして(Math、this)を補数として持っているのですか?
HankH 2009年

@HankH:私の回答へのコメントで、あなたのコメントに対する私の返答を見てください。
Roatin Marth

1
「プロトタイプを使用している場合、ChaosPandionのソリューションが機能する」という意味がわかりません。Mathオブジェクトをコンテキストとして使用していることを除いて、ソリューションはどのように異なりますか?
Ionuț G. Stan

申し訳ありませんが、プロトタイプを拡張すれば機能します。謝罪。
ジェイ

それで、jeeroseとChaosPandionのどちらが良いですか?
HankH 2009年

3

ライブラリsugar.jsを使用する場合は、arr.min()およびarr.max()推奨どおりに記述できます。非数値配列から最小値と最大値を取得することもできます。

min(map、all = false)最小の値を持つ配列の要素を返します。mapは、チェックされる値をマッピングする関数、またはショートカットとして機能する文字列です。allがtrueの場合、配列内のすべての最小値を返します。

max(map、all = false)最大の値を持つ配列の要素を返します。mapは、チェックされる値をマッピングする関数、またはショートカットとして機能する文字列です。allがtrueの場合、配列内のすべての最大値を返します。

例:

[1,2,3].min() == 1
['fee','fo','fum'].min('length') == "fo"
['fee','fo','fum'].min('length', true) == ["fo"]
['fee','fo','fum'].min(function(n) { return n.length; }); == "fo"
[{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2}
['fee','fo','fum'].max('length', true) == ["fee","fum"]

Lo-Dashunderscore.jsなどのライブラリも、同様の強力なminおよびmax関数を提供します。

Lo-Dashの例:

_.max([4, 2, 8, 6]) == 8
var characters = [
  { 'name': 'barney', 'age': 36 },
  { 'name': 'fred',   'age': 40 }
];
_.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }

3
let arr = [2,5,3,5,6,7,1];

let max = Math.max(...arr); // 7
let min = Math.min(...arr); // 1

2
このソリューションは、この質問に対する他の複数の回答者によってすでに提供されています。あなたの答えは何を追加しますか?
Nick

3

試す

let max= a=> a.reduce((m,x)=> m>x ? m:x);
let min= a=> a.reduce((m,x)=> m<x ? m:x);

Math.min / max(+ apply)の場合、エラーが発生します。

呼び出しスタックの最大サイズを超えました(Chrome 74.0.3729.131)

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