Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i use Math.max with an array of objects?

Tags:

javascript

I want to select the biggest number in an array of objects, so for example, I want to get the x property that holds the largest number (in this example, maximum should be 200):

var myArr = [{x:100,y:200},{x:200,y:500}];

//does not work:
var maximum = Math.max.apply(Math,myArr.x);
like image 789
doubleOrt Avatar asked Jan 12 '16 17:01

doubleOrt


5 Answers

You'll have to extract the properties from the objects yourself:

var maximum = Math.max.apply(Math, myArr.map(function(o) { return o.x; }));

That uses .map() to iterate through the elements of the array and return the value of the "x" property. That result array is then passed as the arguments to Math.max().

Now that => functions are widely available it'd be a little shorter as so:

var maximum = Math.max.apply(Math, myArr.map(o => o.x));

Still doing pretty much the exact same thing of course.

like image 146
Pointy Avatar answered Oct 24 '22 14:10

Pointy


One more way, I think it is more beautiful. By using spread:

Math.max(...array.map((i) => i.x));
like image 6
Gena Tretyakov Avatar answered Oct 24 '22 14:10

Gena Tretyakov


var myArr = [{x:100,y:200},{x:200,y:500}];

function sortByKeyDesc(array, key) {
    return array.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
    });
}
console.log(sortByKeyDesc(myArr, "x")[0].x);

first sort by key value in descending order and then get the first object's x property

like image 1
gurvinder372 Avatar answered Oct 24 '22 15:10

gurvinder372


If you want to do it the old fashioned way:

function arrayMax(arr, key){
    var m = -Infinity,
        cur,
        i;
    for(i=0; i<arr.length; i++){
        cur = arr[i][key]
        if(cur > m){
            m = cur;
        }
    }
    return m;
}

This function takes an array of objects as the first argument and a key as the second. It iterates over the array and returns the largest value found for the given key.

In your case, you would call it like this:

var maximum = arrayMax(myArr, "x");

Notice that, unlike Math.max, this is resilient to the case where one (or more) of the objects does not have that key defined, so that:

arrayMax([{y:200}, {x:100, y:100}, {x:300, y:400}], "x");

Will return 300, whereas Math.max returns NaN (on Google chrome, at least). Worst case scenario (none of the objects has the key defined), the arrayMax function returns -Infintity.

If you want to return the object that has the largest value instead of simply returning the value, you can easily modify the function to do so:

function arrayMax(arr, key){
    var m = -Infinity,
        o = null,
        cur,
        curv,
        i;
    for(i=0; i<arr.length; i++){
        cur = arr[i]
        curv = cur[key]
        if(curv > m){
            m = curv;
            o = cur;
        }
    }
    return o;
}
like image 1
user5728855 Avatar answered Oct 24 '22 15:10

user5728855


You need to map the object array to an array of numbers:

Math.max.apply(Math,myArr.map(function(o){return o.x;}))
like image 1
Ameer Hamza Avatar answered Oct 24 '22 14:10

Ameer Hamza