从 JavaScript 对象数组中获取最大值和最小值的最佳方法是什么?
鉴于:
var a = [{x:1,y:0},{x:-1,y:10},{x:12,y:20},{x:61,y:10}];
var minX = Infinity, maxX = -Infinity;
for( var x in a ){
if( minX > a[x].x )
minX = a[x].x;
if( maxX < a[x].x )
maxX = a[x].x;
}
看起来有点笨拙。有没有更优雅的方法,也许使用dojo?
它不会更高效,但只是为了笑:
var minX = Math.min.apply(Math, a.map(function(val) { return val.x; }));
var maxX = Math.max.apply(Math, a.map(function(val) { return val.x; }));
或者如果您愿意使用三行代码:
var xVals = a.map(function(val) { return val.x; });
var minX = Math.min.apply(Math, xVals);
var maxX = Math.max.apply(Math, xVals);
使用这个例子
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);
sort
。此方法会修改原始数组,因此您可能需要克隆它:
var b = [].concat(a); // clones "a"
b.sort(function (a, b) { return a.x - b.x; });
var min = b[0];
var max = b[b.length - 1];
我知道有点太晚了,但对于新用户,你可以使用lodash。它使事情变得简单得多。
var a = [{x:1,y:0},{x:-1,y:10},{x:12,y:20},{x:61,y:10}];
var X = [];
var Y = [];
a.map(function (val) {
X.push(val.x);
Y.push(val.y);
});
var minX = _.min(X);
var minY = _.min(Y);
var maxX = _.max(X);
var maxY = _.max(Y);
或者您可以使用 .sort() 来完成任务,如 procrastinator 所解释的那样。
另一种想法是通过将值减少到一个值来计算最大值/最小值。就时间复杂度而言,这与您的版本完全相同,但思考方式有点不同。 (从 JavaScript 1.8 开始支持
reduce()
。)
var getMax = function (field) {
return a.reduce(function (acc, c) {
return Math.max(c[field], acc);
}, -Infinity);
}
var getMin = function (field) {
return a.reduce(function (acc, c) {
return Math.min(c[field], acc);
}, Infinity);
}
console.log(getMax('x')) //61
console.log(getMin('x')) //-1
console.log(getMax('y')) //20
console.log(getMin('y')) //0
您可以使用
map
功能,但它几乎只是 for
周围的语法糖。任何使用 reduce
的解决方案都会比你的“天真的”慢两倍,因为它会迭代数组一次以获得最小值,并再次迭代最大值。就性能而言,您当前的解决方案几乎是最好的。您所能做的就是通过缓存来减少更多的查找。
万一有人在 2024 年遇到这个问题,我喜欢这个方法:
var a = [{ x: 1, y: 0 }, { x: -1, y: 10 }, { x: 12, y: 20 }, { x: 61, y: 10 }]
const minX = a.reduce((prev, curr) => {
return curr.x < prev.x ? curr : prev
})
const maxX = a.reduce((prev, curr) => {
return curr.x > prev.x ? curr : prev
})