Comment puis-je trouver le plus grand nombre contenu dans un tableau JavaScript?


206

J'ai un simple objet JavaScript Array contenant quelques chiffres.

[267, 306, 108]

Y a-t-il une fonction qui trouverait le plus grand nombre dans ce tableau?


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

Réponses:


315

Resig à la rescousse:

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

avertissement : puisque le nombre maximum d'arguments est aussi bas que 65535 sur certaines machines virtuelles , utilisez une boucle for si vous n'êtes pas certain que le tableau est si petit.


15
Ah, mais maintenant il a l' autocollant de qualité SO apposé sur lui de manière légèrement tordue!
Shog9

2
FWIW, si les performances sont un facteur dans votre solution, je testerais cela par rapport à votre propre fonction facilement codée pour m'assurer qu'elle fonctionne bien. Nous avons tendance à supposer que l'implémentation native sera plus rapide; en fait, le coût de l' applyappel peut le nettoyer très facilement.
TJ Crowder

2
Que faire si la longueur de mon tableau est supérieure à la limite de nombre de paramètres?
lukas.pukenis

3
@CrescentFresh selon ceci: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… il est codé en dur à 65535. Selon ceci: code.google.com/p/v8/issues/detail?id = 172 et en sachant que les arguments sont poussés sur la pile, nous savons que ce n'est pas illimité
lukas.pukenis

9
De plus, cette méthode n'est pas robuste. Il échoue si votre baie est plus grande que la taille de pile maximale, ce qui entraîneRangeError: Maximum call stack size exceeded.
Mark Lundin

197

Vous pouvez utiliser la fonction apply, pour appeler Math.max :

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

Comment ça fonctionne?

La demande fonction est utilisée pour appeler une autre fonction, avec un contexte et des arguments donnés, fournis sous forme de tableau. Les fonctions min et max peuvent prendre un nombre arbitraire d'arguments d'entrée: Math.max (val1, val2, ..., valN)

Donc, si nous appelons:

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

La fonction d'application exécutera:

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

Notez que le premier paramètre, le contexte, n'est pas important pour ces fonctions car elles sont statiques, elles fonctionneront indépendamment de ce qui est passé en tant que contexte.


2
Whoa vous mettez vos réponses avec beaucoup d'efforts: D
ShrekOverflow

1
C'est génial. Mais que se passe-t-il si la longueur de mon tableau dépasse la limite de taille des paramètres (de la fonction)? Et alors?
lukas.pukenis

1
J'aime mieux cette réponse que les autres car elle explique ce que tout fait et pourquoi. +1
Marvin

59

La syntaxe la plus simple, avec le nouvel opérateur d'étalement :

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

Source: Mozilla MDN


2
Cependant, à la fois spread (...) et apply échouent ou retournent le mauvais résultat si le tableau contient trop d'éléments developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Green

@Green FWIW, la limite de nombre de paramètres est 65536 (au moins sur Chrome) ([source ( bugs.webkit.org/show_bug.cgi?id=80797)] ). Donc, si votre tableau contient plus de 65536 éléments, cette réponse ne fonctionnera pas.
mgthomas99

4
65536 devrait être suffisant pour tout le monde
vsync

41

Je ne suis pas un expert JS, mais je voulais voir comment ces méthodes s'empilent, donc c'était une bonne pratique pour moi. Je ne sais pas si c'est techniquement la bonne façon de tester ces performances, mais je les ai juste exécutées l'une après l'autre, comme vous pouvez le voir dans mon code.

Le tri et l'obtention de la valeur 0 est de loin la pire méthode (et cela modifie l'ordre de votre tableau, ce qui n'est peut-être pas souhaitable). Pour les autres, la différence est négligeable sauf si vous parlez de millions d'indices.

Résultats moyens de cinq exécutions avec un tableau de 100 000 indices de nombres aléatoires:

  • réduire a pris 4,0392 ms pour fonctionner
  • Math.max.apply a mis 3,3742 ms pour s'exécuter
  • le tri et l'obtention de la valeur 0 ont pris 67,4724 ms pour s'exécuter
  • Math.max dans Reduce () a pris 6,5804 ms pour s'exécuter
  • la fonction findmax personnalisée a pris 1,6102 ms pour s'exécuter

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
Pour moi, c'est la meilleure réponse à cette question.
rzelek

1
J'ai fait jsperf testspour ce qui précède
vsync

37

J'ai trouvé que pour les tableaux plus gros (~ 100k éléments), il est en fait payant de simplement itérer le tableau avec une humble forboucle, en effectuant environ 30% de mieux que 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;
}

Résultats de référence


3
FWIW, sort à 84% maintenant sur Chrome 31.
Ilan Biala

31

Vous pouvez trier le tableau par ordre décroissant et obtenir le premier élément:

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

4
Je suppose que vous pouvez également trier et obtenir le dernier élément ...?
Shog9

@ Shog9: Oui, mais vous devrez spécifier vous-même la fonction de comparaison:sort(function(a,b){return b-a;})
Gumbo

9
Ah. Je pensais plutôt à:[...].sort().pop()
Shog9

4
"la recherche du nombre prend ordre-n, le tri prend entre ordre (n log n) et ordre (n au carré), en fonction de l'algorithme de tri utilisé" - webmasterworld.com/forum91/382.htm
Marco Luglio

2
Gardez également à l'esprit que cela trie le tableau, ce qui peut ou non être un effet secondaire souhaité. La solution d'application est plus performante et n'a aucun effet secondaire.
Caleb

28

Que dis-tu de ça:

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

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

console.log(largest);

Si j'avais vu cette réponse en premier (actuellement au bas de la liste), j'aurais économisé deux heures.
user139301

1
L'approche Math.max est probablement la plus standard, mais j'obtenais un débordement de pile lorsque le tableau était trop grand (500K). Cette réponse est rapide et efficace et c'est celle que j'ai fini par utiliser moi-même, donc je vote pour celle-ci.
Jay

8

que diriez-vous d'utiliser Array.reduce ?

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

La valeur initiale doit être définie sur -Infinity.
Ja͢ck

@Jack, pourquoi est-ce nécessaire? même avec un tableau de tous les nombres négatifs, j'obtiens un résultat valide.
CodeToad

1
C'est le cas de bord où le tableau est vide.
Ja͢ck

5

Presque toutes les réponses utilisent Math.max.apply()ce qui est agréable et dandy mais a des limites.

Les arguments de fonction sont placés sur une pile qui a un inconvénient - une limite. Donc, si votre tableau est plus grand que la limite, il échouera avecRangeError: Maximum call stack size exceeded.

Pour trouver une taille de pile d'appels, j'ai utilisé ce code:

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

Il s'est avéré être le plus grand sur FireFox sur ma machine - 591519 . Cela signifie que si votre tableau contient plus de 591519 éléments, Math.max.apply()cela entraînera RangeError .

La meilleure solution pour ce problème est la méthode itérative (crédit: 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];
}

J'ai écrit sur cette question sur mon blog ici .


1
Ce n'est pas juste. Je veux la réponse ici, sur SO, pas un autre lien vers une autre ressource tierce. Surtout quand c'est combiné avec "tout ici est mauvais, mais allez, regardez, c'est tellement génial sur mon blog ..."
osa

@SergeyOrshanskiy un lien vers un tiers fonctionne très bien au cas où il serait mis à jour avec de nouvelles informations et solutions. Pas besoin non plus de se sentir offensé. Les gens veulent aussi résoudre vos problèmes. Je voulais aussi le résoudre, alors j'ai écrit à ce sujet sur mon blog
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
Cependant, à la fois spread (...) et apply échouent ou retournent le mauvais résultat si le tableau contient trop d'éléments developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Green

5

Trouver la valeur maximale et minimale de manière simple et manuelle. Ce code est beaucoup plus rapide que Math.max.apply; J'ai essayé jusqu'à 1000k nombres dans le tableau.

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()donne le mauvais résultat s'il n'y a que des nombres négatifs dans le tableau; findmin()donne le mauvais résultat pour un tableau vide.
Ja͢ck


3

Oui bien sûr existent: Math.max.apply(null,[23,45,67,-45]) et le résultat revient 67;



1

Ne pas oublier que l'emballage peut être fait avec Function.prototype.bind, vous donnant un « tout-native » fonction .

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

1

Vous pouvez également étendre Arraycette fonction et l'intégrer à chaque tableau.

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

console.log( myArray.max() );

1
Terriblement inefficace.
Frank Schmitt

@FrankSchmitt, merci, je suis d'accord. La réponse originale n'était pas une bonne solution. Le tri par défaut ne trie pas les nombres, il traite les éléments comme des chaînes. Modifié ma réponse pour avoir le bon type.
Izz

Cela n'était pas mon point de vue. Le tri d'un tableau pour trouver le maximum est en soi terriblement inefficace, car il faut au moins N log N opérations, tandis que la recherche du maximum peut être effectuée dans N opérations.
Frank Schmitt

1

Vous pouvez également utiliser 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

Utiliser - Array.prototype.reduce()c'est cool!

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

acc = accumulateur et val = valeur actuelle ;

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

console.log(a);


1

Vous pouvez essayer ça,

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

Je viens de commencer avec JS mais je pense que cette méthode serait bien:

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

Cela aura des problèmes s'il arrayne contient que des nombres négatifs.
Teepeemm

0

Trouver le plus grand nombre dans un tableau multidimensionnel

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;

Il est toujours conseillé d'ajouter des explications détaillées à votre code, surtout s'il existe déjà plusieurs autres réponses. Pourquoi est-ce différent / meilleur?
Bowdzone

@Bowdzone, merci pour le commentaire. cette façon est très basique ce qui la rend simple à comprendre avec un peu de connaissance de quelques méthodes seulement.
Liveindream

Cela ne renvoie pas le plus grand nombre, il renvoie un tableau du plus grand nombre de chaque tableau dans le tableau multidimensionnel. Vous devrez ajouter par exemple var tmax = Math.max.apply(Math, max), ou mieux encore, utiliser une fermeture d'une fonction de boucle, par exemple dans stackoverflow.com/a/54980012/7438857 . Avec cette modification, il est préférable de répondre à une question distincte, comment "trouvez-vous le plus grand nombre dans un tableau multidimensionnel", ou sur stackoverflow.com/questions/32616910/… . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
James Ray

stackoverflow.com/a/32617019/7438857 est une meilleure réponse à la bonne question, tandis que cette réponse ne répond pas à la question ci-dessus, elle renvoie le plus grand nombre de chaque tableau dans un tableau multidimensionnel.
James Ray

0

Lance ça:

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

Et maintenant essayez les [3,10,2].max()retours10


0

Rechercher les valeurs Max et Min à l'aide du tri à bulles

    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) Les tableaux Javascript ont déjà une fonction de tri O (n log n). (2) Le tri des bulles est O (n ^ 2). (3) Trouver le min et le max est O (n).
Teepeemm

0

Essaye ça

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
Cette réponse est-elle sensiblement différente de la plupart des autres sur cette page?
Teepeemm

0

Selon le commentaire de @ Quasimondo , qui semble avoir été largement manqué, ce qui suit semble avoir les meilleures performances comme indiqué ici: https://jsperf.com/finding-maximum-element-in-an-array . Notez que tandis que pour le tableau dans la question, les performances peuvent ne pas avoir un effet significatif, pour les tableaux de grande taille, les performances deviennent plus importantes, et encore une fois, comme indiqué, l' utilisation Math.max()ne fonctionne même pas si la longueur du tableau est supérieure à 65 535. Voir également cette réponse .

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

Une approche récursive sur la façon de le faire en utilisant des opérateurs ternaires

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/ofSolution à une boucle:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.