Нахождение максимального значения атрибута в массиве объектов

Я ищу действительно быстрый, чистый и эффективный способ получить максимальное значение "y" в следующем фрагменте JSON:

[{"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}]

Является ли цикл for единственный способ сделать это? Я заинтересован в том, чтобы как-то использовать Math.max,

27 ответов

Решение

Найти максимум y стоимость объектов в array:

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

Найти объект, свойство которого "X" имеет наибольшее значение в массиве объектов

Одним из способов было бы использовать 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/ (IE9 и выше)

Если вам не нужна поддержка IE (только Edge) или вы можете использовать прекомпилятор, такой как Babel, вы можете использовать более краткий синтаксис.

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

Чистый и простой ES6 (Бабель)

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

Второй параметр должен обеспечивать значение по умолчанию, если arrayToSearchIn пустой.

Сравнение дерева ONELINERS, которые обрабатывают регистр минус чисел (ввод в a массив):

var maxA = Math.max(...a.map(o=>o.y),a[0].y); // 33chars time complexity: >O(2n)

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

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

редактируемый пример здесь. Идеи от: maxA, maxB, maxC (побочный эффект: изменен a - sort на месте).

Я хотел бы объяснить шаг за шагом принятый ответ:

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

Дальнейшая информация:

  • Math.max.apply()
  • Array.prototype.map()
  • Array.from()
  • Function.prototype.apply()
  • Array.prototype.filter()
  • Array.prototype.find()

Ну, во-первых, вы должны проанализировать строку JSON, чтобы вы могли легко получить доступ к ее членам:

var arr = $.parseJSON(str);

Использовать map Метод извлечения значений:

arr = $.map(arr, function(o){ return o.y; });

Затем вы можете использовать массив в max метод:

var highest = Math.max.apply(this,arr);

Или как однострочник:

var highest = Math.max.apply(this,$.map($.parseJSON(str), function(o){ return o.y; }));

Вот кратчайшее решение (One Liner) ES6:

Math.max(...values.map(o => o.y));

Если вы (или кто-то здесь) можете свободно использовать lodash служебная библиотека, она имеет функцию maxBy, которая была бы очень удобна в вашем случае.

следовательно, вы можете использовать как таковой:

_.maxBy(jsonSlice, 'y');

Или простой вид! Сохраняя это реальным:)

array.sort((a,b)=>a.y<b.y)[0].y
      let List= [{votes:4},{votes:8},{votes:7}]

let objMax = List.reduce((max, curren) => max.votes > curren.votes ? max : curren);

console.log(objMax)

Каждый массив и получить максимальное значение с Math.

data.reduce((max, b) => Math.max(max, b.costo), data[0].costo);
var data = [
  { 'name': 'Vins', 'age': 27 },
  { 'name': 'Jan', 'age': 38 },
  { 'name': 'Alex', 'age': 80 },
  { 'name': 'Carl', 'age': 25 },
  { 'name': 'Digi', 'age': 40 }
];
var max = data.reduce(function (prev, current) {
   return (prev.age > current.age) ? prev : current
});
//output = {'name': 'Alex', 'age': 80}

Он возвращает упрощенный объект @andy polhill.

Решение ES6

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

Для получения дополнительной информации см. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

var max = 0;                
jQuery.map(arr, function (obj) {
  if (obj.attr > max)
    max = obj.attr;
});

Спасибо за ответы, которые я нашел здесь, я надеюсь, что это может быть полезно для кого-то. Эту машинописную функцию можно вызвать для поиска наибольшего значения, которое может существовать в поле объектов массива:

      function getHighestField(objArray: any[], fieldName: string) {
  return Number(
    Math.max.apply(
      Math,
      objArray?.map(o => o[fieldName] || 0),
    ) || 0,
  );
}

С этими значениями в качестве примера:

      const scoreBoard = [
  { name: 'player1', score: 4 },
  { name: 'player2', score: 9 },
  { name: 'player3', score: 7 }
]

Вы можете вызвать функцию следующим образом:

      const myHighestVariable = `This is the highest: ${getHighestField(scoreBoard, "score")}`;

Результат будет примерно таким:

      console.log(myHighestVariable);

Это самое высокое: 9

Объяснение принятого ответа и более общий способ

Если кто-то здесь, чтобы найти максимальное значение среди всех таких ключей (обобщенный способ):

одна вещь, чтобы отметить, что Math.max(1, 2, 3) возвращается 3. Так делает Math.max(...[1, 2, 3]), поскольку синтаксис Spread можно использовать, когда все элементы объекта или массива необходимо включить в какой-либо список.

Мы воспользуемся этим!

Предположим, что массив выглядит так:

      var a = [{a: 1, b: 2}, {foo: 12, bar: 141}]

И цель - найти максимум (среди любых атрибутов) (вот он bar(141))

так использовать Math.max() нам нужны значения в одном массиве (так что мы можем сделать ...arr)

Сначала давайте просто разделим все числа, которые мы можем каждое, что каждый элемент массива aэто объект. Перебирая каждый из них, Object.values(item) предоставит нам все значения этого элемента в виде массива, и мы можем использовать map чтобы сгенерировать новый массив только со значениями

Так,

      var p = a.map(item => Object.values(item)) // [ [1, 2], [12, 141] ]

Кроме того, используя concat,

[].concat([], ...arr), или просто [].concat(...arr) по прибытии, [ [1, 2], [12, 141] ] сглаживает это до [1, 2, 12, 141]

Так,

      var f = [].concat(...p) // [1, 2, 12, 141]

поскольку теперь у нас есть массив только чисел, мы выполняем Math.max (...f):

      var m = Math.max(...f) // 141
Here is very simple way to go:

Your DataSet.

let numberArray = [
  {
    "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
  }
]

1. First create Array, containing all the value of Y
let result = numberArray.map((y) => y)
console.log(result) >> [0.026572007,0.025057454,0.024530916,0.031004457]

2. let maxValue = Math.max.apply(null, result)
console.log(maxvalue) >> 0.031004457

Быстро и грязно:

Простое уменьшение с отрицательной бесконечностью по умолчанию? Делает то, что вам нужно в одной итерации / операции...

array.reduce((last,current)=>current.y>last?current.y:last,-Infinity)

Это очень просто

           const array1 = [
  {id: 1, val: 60},
  {id: 2, val: 2},
  {id: 3, val: 89},
  {id: 4, val: 78}
];
const array2 = [1,6,8,79,45,21,65,85,32,654];
const max = array1.reduce((acc, item) => acc = acc > item.val ? acc : item.val, 0);
const max2 = array2.reduce((acc, item) => acc = acc > item ? acc : item, 0);

console.log(max);
console.log(max2);
function getMaxProperty(arrayOfObjects, property) {
    const arrayOfValues = arrayOfObjects.map(obj => obj[property]);
    return Math.max(...arrayOfValues);
}

Основано на отличном ответе от @tobyodavies.

Попробуйте это ниже рабочего примера.

var t = [{"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}]
Math.max.apply(Math,t.map(function(o){return o.y;}))

осторожны с нулевым и пустым и свойством не в массиве и пустом массиве

      if ((value && value.length > 0)) {
  var maxObj = (value && value.length > 0) value.reduce(function (prev, current) {
    return ((parseInt(prev["y"]) || 0) > (parseInt(current["y"]) || 0)) ? prev : current
  })
}
{
  // else logic here
}

Немного скепсиса по поводу ответа Энди: перед сокращением можно использовать фильтр, чтобы избежать передачи пустых массивов, которые могут все испортить.

      const max = data
.filter(item=>item.id != undefined) // --> here
.reduce(function(prev, current) {return (prev.y > current.y) ? prev : current
    }) //returns object

const getMaxFromListByField = (список, поле) => {return list[list.map(it => it[field]).indexOf(Math.max(...list.map(it => it[поле])))]}

use this both :  

obj = Math.max.apply(Math,data.map(function(o){return o.partsCount;}));

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};
Другие вопросы по тегам