比较JavaScript对象数组以获取最小/最大值
我有一个对象数组,我想比较特定的对象属性上的这些对象。 这是我的数组:
var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ]
我想特别注意“成本”,并得到一个最小值和最大值。 我意识到我可以抓住成本值,并把它们推到一个JavaScript数组,然后运行快速JavaScript最大/最小值 。
但有没有一种更简单的方法来绕过中间的数组步骤,并直接脱离对象的属性(在这种情况下,“成本”)呢?
在这种情况下,最快的方法是循环遍历所有元素,并将其与最高/最低值进行比较。
(创build一个数组,调用数组方法是这个简单的操作矫枉过正)。
// 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);
reduce对于这样的东西是有好处的:在一个对象数组上执行集合操作(如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]
我认为Rob 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"));
或者如果你有一个深深的嵌套结构,你可以得到更多的function,并执行以下操作:
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; }));
这些可以很容易地被卷入更有用/特定的forms。
使用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));
使用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;
这是更好的解决scheme
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);
添加到Tristan Reid的答案(+使用es6),你可以创build一个函数,接受一个callback,它将包含你想要应用到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);
您可以使用内置的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
另一个,类似于肯尼贝克的答案,但都在一行:
maxsort = myArray.slice(0).sort(function (a, b) { return b.ID - a.ID })[0].ID;