可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
What is the best way to get the maximum and minimum values from a JavaScript array of objects?
Given:
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;
}
Seems a bit clumsy. Is there a more elegant way, perhaps using dojo?
回答1:
Use this example
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);
回答2:
It won't be more efficient, but just for grins:
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; }));
Or if you're willing to have three lines of code:
var xVals = a.map(function(val) { return val.x; });
var minX = Math.min.apply(Math, xVals);
var maxX = Math.max.apply(Math, xVals);
回答3:
You could use sort
. This method modifies the original array, so you might need to clone it :
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];
回答4:
I know its a little too late, but for newer users you could use lodash. It makes the stuff a lot simpler.
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);
Or you could use .sort() to the task as procrastinator explained.
回答5:
Another idea is to calculate max/min by reducing the values to one value. This is exactly same as your version in terms of time complexity but a bit different way to think. (reduce()
is supported since JavaScript 1.8.)
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
回答6:
You can use map
functionality, but it is pretty much just a syntactic sugar around for
. Any solution using reduce
would be twice as slow as your "naive" because it would iterate array once for min value and once more for max. Your current solution is pretty much the best you can have in terms of performance. All you can do is to shave off some more lookups by caching them.