从JavaScript数组中获取对象值的最大值和最小值

从JavaScript数组中获取对象值的最大值和最小值,javascript,performance,dojo,Javascript,Performance,Dojo,从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; } var

从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;
}
var a=[{x:1,y:0},{x:-1,y:10},{x:12,y:20},{x:61,y:10}];
var minX=无穷大,maxX=-无穷大;
对于(a中的var x){
如果(minX>a[x].x)
minX=a[x].x;
if(maxX
看起来有点笨拙。有没有更优雅的方法,比如使用dojo?

使用这个例子

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);
var lower=Number.POSITIVE_∞;
var highest=Number.NEGATIVE_无穷大;
var-tmp;
对于(var i=myArray.length-1;i>=0;i--){
tmp=myArray[i]。成本;
如果(tmp<最低)最低=tmp;
如果(tmp>最高)最高=tmp;
}
console.log(最高、最低);

另一个想法是通过将值减少到一个值来计算最大/最小值。就时间复杂性而言,这与您的版本完全相同,但思考方式略有不同。(
reduce()
自JavaScript 1.8以来一直受支持。)

你可以用。此方法会修改原始阵列,因此您可能需要克隆它:

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];

您可以使用
map
功能,但它几乎只是
对于
的一种语法糖分。任何使用
reduce
的解决方案的速度都是“naive”的两倍,因为它会对数组进行一次最小值迭代,对最大值迭代一次。就性能而言,您当前的解决方案几乎是您所能拥有的最佳解决方案。你所能做的就是通过缓存来减少更多的查找。

这不会更有效,但只适用于露齿而笑的人:

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

或者你可以用拖延者的解释来完成任务。

这不仅在原则上与问题相同,而且实际上效率较低。不需要那个额外的变量。你说的是
tmp
?它更有效,因为它避免了重复查找。这个变量是绝对需要的。@Brad-除非我弄错了,否则它实际上比使用数组索引而不是for/in循环的OP算法的版本还要快。啊,我现在明白了!我根本没注意。很抱歉我投了反对票。你仍然可以通过使用常量整数,而不是混合整数和双精度,以及通过循环转发,使这个速度提高35%。请注意,这个jsperf通常是坏的,所有的代码都应该被提取到非重复函数中,并且这些函数在开始计时之前都应该进行适当的预热。很好的一个:)我认为
Math.max/min
不接受两个以上的参数。@wared尽管很遗憾,它是最慢的一个:)对我来说很遗憾,考虑到你的诚实,我不能说这个测试被操纵了:我现在知道apply做什么了。谢谢。ES6的aproach应该是:
constxvals=a.map((val)=>val.x);const minValue=Math.min(…xVals);常量maxValue=Math.max(…xVals)使用下面的一些算法感谢jsPerf测试链接。这是一个伟大的资源!@sza可能复制reduce版本的一个变体(更多的苹果对苹果),实际上比OP的for/in循环稍微快一些:@user123444555621 OP确实提到了“优雅”,但也标记了问题[performance]。不需要
acc=
部分,只需
返回Math.max(c[field],acc)@Pumbaa80 Thx。更新。效率较低。sort()是nlogn,这比OP发布时的O(n)慢。@sza在这种情况下,OP使用的数组上的for in循环似乎比sort方法慢,这也让我感到惊讶。@dc5因为元素的数量。性能通常取决于随着元件数量的增加,效率如何恶化。用1000多个对象试试看。@sza-我确实这么做了,而且我理解了这些数字,我应该更清楚地知道,让我吃惊的是,即使在排序中有复制和回调的开销,但即使在较小的大小上,速度也更快。
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);