У меня есть массив объектов, и я хочу сравнить эти объекты по определенному свойству объекта. Вот мой массив:
var myArray = [
{"ID": 1, "Cost": 200},
{"ID": 2, "Cost": 1000},
{"ID": 3, "Cost": 50},
{"ID": 4, "Cost": 500}
]
Я хотел бы сосредоточиться на «стоимости» конкретно и получить минимальное и максимальное значение. Я понимаю, что могу просто получить значения стоимости и поместить их в массив javascript, а затем запустить Fast JavaScript Max / Min .
Однако есть ли более простой способ сделать это, пропустив шаг массива посередине и напрямую отключив свойства объекта (в данном случае «Стоимость»)?
javascript
arrays
compare
стреляющий
источник
источник
lowest=highest=myArray[0]
а затем начать цикл с 1.myArray[0].Cost
, хотя. Но, если первого элемента нет, будет выдана ошибка. Итак, необходима дополнительная проверка, которая, возможно, отменит небольшой прирост производительности.var lowestObject; for (...)
иif (tmp < lowest) { lowestObject = myArray[i]; lowest = tmp; }
Уменьшение хорошо подходит для таких вещей: выполнять агрегированные операции (например, min, max, avg и т. Д.) Над массивом объектов и возвращать один результат:
myArray.reduce(function(prev, curr) { return prev.Cost < curr.Cost ? prev : curr; });
... или вы можете определить эту внутреннюю функцию с синтаксисом функции ES6:
Если вы хотите быть милым, вы можете прикрепить это к массиву:
Array.prototype.hasMin = function(attrib) { return (this.length && this.reduce(function(prev, curr){ return prev[attrib] < curr[attrib] ? prev : curr; })) || null; }
Теперь вы можете просто сказать:
myArray.hasMin('ID') // result: {"ID": 1, "Cost": 200} myArray.hasMin('Cost') // result: {"ID": 3, "Cost": 50} myEmptyArray.hasMin('ID') // result: null
Обратите внимание, что если вы собираетесь использовать это, он не имеет полной проверки для каждой ситуации. Если вы передадите массив примитивных типов, это не удастся. Если вы проверите свойство, которое не существует, или если не все объекты содержат это свойство, вы получите последний элемент. Эта версия немного более громоздкая, но имеет следующие проверки:
Array.prototype.hasMin = function(attrib) { const checker = (o, i) => typeof(o) === 'object' && o[i] return (this.length && this.reduce(function(prev, curr){ const prevOk = checker(prev, attrib); const currOk = checker(curr, attrib); if (!prevOk && !currOk) return {}; if (!prevOk) return curr; if (!currOk) return prev; return prev[attrib] < curr[attrib] ? prev : curr; })) || null; }
источник
prev.Cost
будет неопределенным? Или он запускается как 0?Используйте
sort
, если вас не волнует модифицируемый массив.myArray.sort(function (a, b) { return a.Cost - b.Cost }) var min = myArray[0], max = myArray[myArray.length - 1]
источник
myArray
, чего нельзя ожидать.O(nlog(n))
обход массива:O(n)
Используйте
Math
функции и выбирайте нужные вам значенияmap
.Вот jsbin:
https://jsbin.com/necosu/1/edit?js,console
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));
источник
apply
. Проще говоря -Math.min(...myArray.map(o => o.Cost))
найти минимум иMath.max(...myArray.map(o => o.Cost))
найти максимум.Я думаю, что ответ Роба В. действительно правильный (+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.max.apply(Math, myArray.map(a => a.Cost));
для мин
Math.min.apply(Math, myArray.map(a => a.Cost));
источник
Попробуйте (
a
это массив,f
это поле для сравнения)let max= (a,f)=> a.reduce((m,x)=> m[f]>x[f] ? m:x); let min= (a,f)=> a.reduce((m,x)=> m[f]<x[f] ? m:x);
Показать фрагмент кода
let max= (a,f)=> a.reduce((m,x)=> m[f]>x[f] ? m:x); let min= (a,f)=> a.reduce((m,x)=> m[f]<x[f] ? m:x); // TEST var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] console.log('Max Cost', max(myArray, 'Cost')); console.log('Min Cost', min(myArray, 'Cost')); console.log('Max ID', max(myArray, 'ID')); console.log('Min ID', min(myArray, 'ID'));
источник
Используя Array.prototype.reduce () , вы можете подключить функции компаратора для определения минимального, максимального и т. Д. Элемента в массиве.
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;
источник
Использование
Math.min
иMath.max
:var myArray = [ { id: 1, cost: 200}, { id: 2, cost: 1000}, { id: 3, cost: 50}, { id: 4, cost: 500} ] var min = Math.min(...myArray.map(item => item.cost)); var max = Math.max(...myArray.map(item => item.cost)); console.log("min: " + min); console.log("max: " + max);
источник
Это более лучшее решение
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);
источник
Добавив к ответу Тристана Рейда (+ используя 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);
источник
Этого можно добиться с помощью lodash
minBy
иmaxBy
functions.Lodash
minBy
иmaxBy
документацияРешение
var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] const minimumCostItem = _.minBy(myArray, "Cost"); console.log("Minimum cost item: ", minimumCostItem); // Getting the maximum using a functional iteratee const maximumCostItem = _.maxBy(myArray, function(entry) { return entry["Cost"]; }); console.log("Maximum cost item: ", maximumCostItem);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
источник
1, собственный способ java-скрипта
2, сначала объект сортировки, затем легко получить минимальный максимум из отсортированного объекта
//first approach var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] var t1 = performance.now();; let max=Math.max.apply(Math, myArray.map(i=>i.Cost)) let min=Math.min.apply(Math, myArray.map(i=>i.Cost)) var t2 = performance.now();; console.log("native fuction took " + (t2 - t1) + " milliseconds."); console.log("max Val:"+max) console.log("min Val:"+min) // Second approach: function sortFunc (a, b) { return a.Cost - b.Cost } var s1 = performance.now();; sortedArray=myArray.sort(sortFunc) var minBySortArray = sortedArray[0], maxBySortArray = sortedArray[myArray.length - 1] var s2 = performance.now();; console.log("sort funciton took " + (s2 - s1) + " milliseconds."); console.log("max ValBySortArray :"+max) console.log("min Val BySortArray:"+min)
источник
Для краткого современного решения можно выполнить
reduce
операцию над массивом, отслеживая текущие минимальные и максимальные значения, поэтому массив повторяется только один раз (что оптимально).let [min, max] = myArray.reduce(([prevMin,prevMax], {Cost})=> [Math.min(prevMin, Cost), Math.max(prevMax, Cost)], [Infinity, -Infinity]);
Демо:
Показать фрагмент кода
var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] let [min, max] = myArray.reduce(([prevMin,prevMax], {Cost})=> [Math.min(prevMin, Cost), Math.max(prevMax, Cost)], [Infinity, -Infinity]); console.log("Min cost:", min); console.log("Max cost:", max);
источник
Еще один, похожий на ответ Кеннебека, но все в одной строке:
maxsort = myArray.slice(0).sort(function (a, b) { return b.ID - a.ID })[0].ID;
источник
Вместо этого вы можете использовать встроенный объект Array, чтобы использовать Math.max / Math.min:
var arr = [1,4,2,6,88,22,344]; var max = Math.max.apply(Math, arr);// return 344 var min = Math.min.apply(Math, arr);// return 1
источник