631 votes

Trouver la valeur maximale d'un attribut dans un tableau d'objets

Je cherche un moyen vraiment rapide, propre et efficace d'obtenir la valeur maximale de "y" dans la tranche JSON suivante :

[
  {
    "x": "8/11/2009",
    "y": 0.026572007
  },
  {
    "x": "8/12/2009",
    "y": 0.025057454
  },
  {
    "x": "8/13/2009",
    "y": 0.024530916
  },
  {
    "x": "8/14/2009",
    "y": 0.031004457
  }
]

Est-ce qu'un for-loop est la seule façon de procéder ? J'ai envie d'utiliser d'une manière ou d'une autre Math.max .

1037voto

tobyodavies Points 7815

Pour trouver le maximum y valeur des objets dans array :

Math.max.apply(Math, array.map(function(o) { return o.y; }))

451voto

Andy Polhill Points 291

Trouvez l'objet dont la propriété "Y" a la plus grande valeur dans un tableau d'objets.

Un moyen serait d'utiliser Array reduce

const max = data.reduce(function(prev, current) {
    return (prev.y > current.y) ? prev : current
}) //returns object

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce http://caniuse.com/#search=reduce (IE9 et plus)

Si vous n'avez pas besoin de prendre en charge IE (uniquement Edge), ou si vous pouvez utiliser un précompilateur tel que Babel, vous pouvez utiliser la syntaxe plus concise.

const max = data.reduce((prev, current) => (prev.y > current.y) ? prev : current)

251voto

Vitaliy Kotov Points 3342

ES6 (Babel) propre et simple

const maxValueOfY = Math.max(...arrayToSearchIn.map(o => o.y), 0);

Le deuxième paramètre doit assurer une valeur par défaut si arrayToSearchIn est vide.

146voto

Kamil Kiełczewski Points 6496

Comparaison de trois ONELINERS qui gère les cas de nombres négatifs (entrée dans a ) :

var maxA = a.reduce((a,b)=>a.y>b.y?a:b).y; // 30 chars time complexity:  O(n)

var maxB = a.sort((a,b)=>b.y-a.y)[0].y;    // 27 chars time complexity:  O(nlogn)

var maxC = Math.max(...a.map(o=>o.y));     // 26 chars time complexity: >O(2n)

exemple modifiable ici . Idées de : maxA , maxB y maxC (l'effet secondaire de maxB est que le tableau a est modifié parce que sort est en place).

var a = [
  {"x":"8/11/2009","y":0.026572007},{"x":"8/12/2009","y":0.025057454},    
  {"x":"8/14/2009","y":0.031004457},{"x":"8/13/2009","y":0.024530916}
]

var maxA = a.reduce((a,b)=>a.y>b.y?a:b).y;
var maxC = Math.max(...a.map(o=>o.y));
var maxB = a.sort((a,b)=>b.y-a.y)[0].y;

document.body.innerHTML=`<pre>maxA: ${maxA}\nmaxB: ${maxB}\nmaxC: ${maxC}</pre>`;

Pour les tableaux plus grands, la Math.max... entraînera une exception : La taille maximale de la pile d'appels est dépassée (Chrome 76.0.3809, Safari 12.1.2, date 2019-09-13)

let a = Array(400*400).fill({"x": "8/11/2009", "y": 0.026572007 }); 

// Exception: Maximum call stack size exceeded

try {
  let max1= Math.max.apply(Math, a.map(o => o.y));
} catch(e) { console.error('Math.max.apply:', e.message) }

try {
  let max2= Math.max(...a.map(o=>o.y));
} catch(e) { console.error('Math.max-map:', e.message) }

Benchmark pour le réseau à 4 éléments

31voto

congusbongus Points 2260

J'aimerais expliquer le réponse acceptée laconique étape par étape :

var objects = [{ x: 3 }, { x: 1 }, { x: 2 }];

// array.map lets you extract an array of attribute values
var xValues = objects.map(function(o) { return o.x; });
// es6
xValues = Array.from(objects, o => o.x);

// function.apply lets you expand an array argument as individual arguments
// So the following is equivalent to Math.max(3, 1, 2)
// The first argument is "this" but since Math.max doesn't need it, null is fine
var xMax = Math.max.apply(null, xValues);
// es6
xMax = Math.max(...xValues);

// Finally, to find the object that has the maximum x value (note that result is array):
var maxXObjects = objects.filter(function(o) { return o.x === xMax; });

// Altogether
xMax = Math.max.apply(null, objects.map(function(o) { return o.x; }));
var maxXObject = objects.filter(function(o) { return o.x === xMax; })[0];
// es6
xMax = Math.max(...Array.from(objects, o => o.x));
maxXObject = objects.find(o => o.x === xMax);

document.write('<p>objects: ' + JSON.stringify(objects) + '</p>');
document.write('<p>xValues: ' + JSON.stringify(xValues) + '</p>');
document.write('<p>xMax: ' + JSON.stringify(xMax) + '</p>');
document.write('<p>maxXObjects: ' + JSON.stringify(maxXObjects) + '</p>');
document.write('<p>maxXObject: ' + JSON.stringify(maxXObject) + '</p>');

Pour plus d'informations :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X