Сравните массив объектов JavaScript, чтобы получить Min / Max
У меня есть массив объектов, и я хочу сравнить эти объекты с определенным свойством объекта. Вот мой массив:
var myArray = [
{"ID": 1, "Cost": 200},
{"ID": 2, "Cost": 1000},
{"ID": 3, "Cost": 50},
{"ID": 4, "Cost": 500}
]
Я хотел бы обнулить "стоимость" конкретно и получить минимальное и максимальное значение. Я понимаю, что могу просто захватить значения стоимости и оттолкнуть их в массив javascript, а затем запустить Быстрый JavaScript Max / Min.
однако есть ли более простой способ сделать это, обойдя шаг массива в середине и выйдя свойства объектов (в данном случае "стоимость") напрямую?
10 ответов:
самый быстрый способ, в этом случае, петля через все элементы, и сравнить его с самым высоким/самым низким значением, до сих пор.
(Создание массива, вызов методов массива является излишним для этой простой операции).
// There's no real number bigger than plus Infinity var lowest = Number.POSITIVE_INFINITY; var highest = Number.NEGATIVE_INFINITY; var tmp; for (var i=myArray.length-1; i>=0; i--) { tmp = myArray[i].Cost; if (tmp < lowest) lowest = tmp; if (tmp > highest) highest = tmp; } console.log(highest, lowest);
сокращение хорошо подходит для таких вещей: для выполнения агрегатных операций (например, min, max, avg и т. д.) на массиве объектов и возвращает один результат:
myArray.reduce(function(prev, curr) { return prev.Cost < curr.Cost ? prev : curr; });
Если вы хотите быть симпатичным, вы можете прикрепить это к массиву:
Array.prototype.hasMin = function(attrib) { return this.reduce(function(prev, curr){ return prev[attrib] < curr[attrib] ? prev : curr; }); }
Теперь вы можете просто сказать:
myArray.hasMin('ID') // result: {"ID": 1, "Cost": 200} myArray.hasMin('Cost') // result: {"ID": 3, "Cost": 50}
использовать
sort
, если вы не заботитесь об изменении массива.myArray.sort(function (a, b) { return a.Cost - b.Cost }) var min = myArray[0], max = myArray[myArray.length - 1]
Я думаю ответ Роба W действительно правильный (+1), но просто для удовольствия: если вы хотели быть "умным", вы может сделать что-то вроде этого:
var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] function finder(cmp, arr, attr) { var val = arr[0][attr]; for(var i=1;i<arr.length;i++) { val = cmp(val, arr[i][attr]) } return val; } alert(finder(Math.max, myArray, "Cost")); alert(finder(Math.min, myArray, "Cost"));
или если бы у вас была глубоко вложенная структура, вы могли бы получить немного более функциональную и сделать следующее:
var myArray = [ {"ID": 1, "Cost": { "Wholesale":200, Retail: 250 }}, {"ID": 2, "Cost": { "Wholesale":1000, Retail: 1010 }}, {"ID": 3, "Cost": { "Wholesale":50, Retail: 300 }}, {"ID": 4, "Cost": { "Wholesale":500, Retail: 1050 }} ] function finder(cmp, arr, getter) { var val = getter(arr[0]); for(var i=1;i<arr.length;i++) { val = cmp(val, getter(arr[i])) } return val; } alert(finder(Math.max, myArray, function(x) { return x.Cost.Wholesale; })); alert(finder(Math.min, myArray, function(x) { return x.Cost.Retail; }));
они могут быть легко Карри в более полезные/конкретные формы.
использовать
Math
функции и вырвать значения, которые вы хотите сmap
.вот jsbin:
https://jsbin.com/necosu/1/edit?js, консоль
var myArray = [{ "ID": 1, "Cost": 200 }, { "ID": 2, "Cost": 1000 }, { "ID": 3, "Cost": 50 }, { "ID": 4, "Cost": 500 }], min = Math.min.apply(null, myArray.map(function(item) { return item.Cost; })), max = Math.max.apply(null, myArray.map(function(item) { return item.Cost; })); console.log('min', min);//50 console.log('max', max);//1000
обновление:
если вы хотите использовать ES6:
var min = Math.min.apply(null, myArray.map(item => item.Cost)), max = Math.max.apply(null, myArray.map(item => item.Cost));
Это более лучшее решение
var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] var lowestNumber = myArray[0].Cost; var highestNumber = myArray[0].Cost; myArray.forEach(function (keyValue, index, myArray) { if(index > 0) { if(keyValue.Cost < lowestNumber){ lowestNumber = keyValue.Cost; } if(keyValue.Cost > highestNumber) { highestNumber = keyValue.Cost; } } }); console.log('lowest number' , lowestNumber); console.log('highest Number' , highestNumber);
С помощью массив.прототип.уменьшить(), вы можете подключить функции компаратора определить минимальное, максимальное и т. д. элемент в массиве.
var items = [ { name : 'Apple', count : 3 }, { name : 'Banana', count : 10 }, { name : 'Orange', count : 2 }, { name : 'Mango', count : 8 } ]; function findBy(arr, key, comparatorFn) { return arr.reduce(function(prev, curr, index, arr) { return comparatorFn.call(arr, prev[key], curr[key]) ? prev : curr; }); } function minComp(prev, curr) { return prev < curr; } function maxComp(prev, curr) { return prev > curr; } document.body.innerHTML = 'Min: ' + findBy(items, 'count', minComp).name + '<br />'; document.body.innerHTML += 'Max: ' + findBy(items, 'count', maxComp).name;
добавив ответ Тристана Рида (+ с помощью es6), вы можете создать функцию, которая принимает обратный вызов, которая будет содержать оператор, который вы хотите применить к
prev
иcurr
:const compare = (arr, key, callback) => arr.reduce((prev, curr) => (callback(prev[key], curr[key]) ? prev : curr), {})[key]; // remove `[key]` to return the whole object
тогда вы можете просто назвать его с помощью:
const costMin = compare(myArray, 'Cost', (a, b) => a < b); const costMax = compare(myArray, 'Cost', (a, b) => a > b);