23

I'm trying to create a JavaScript function which takes information from an array in an external JSON and then takes the max value (or the top 5 values) for one of the JSON variables. For this example, let's say I want to get the max value for the value "ppg". Here is a small sample of the array:

[
{
    "player" : "Andre Drummond",
    "team" : "Detroit Pistons",
    "ppg" : "15.4",
    "rpg" : "11.6",
    "apg" : "2.4",
    "bpg" : "1.6",
    "spg" : "0.8",
    "3pg" : "0.1"
},
{
    "player" : "Anthony Davis",
    "team" : "New Orleans Pelicans",
    "ppg" : "16.4",
    "rpg" : "13.6",
    "apg" : "2.6",
    "bpg" : "3.5",
    "spg" : "1.2",
    "3pg" : "0.1"
},
{
    "player" : "Carmelo Anthony",
    "team" : "New York Knicks",
    "ppg" : "27.4",
    "rpg" : "5.4",
    "apg" : "4.5",
    "bpg" : "1.1",
    "spg" : "1.5",
    "3pg" : "1.6"
}
]

What would be the best way to go through the array to get the max value and then get the values "player" and "team" from this value? The page will be interactive, as I will have a drop-down menu bar with allows the viewer to choose between one of the six JSON values aside from "player" and "team". Thanks in advance!

Les Paul
  • 1,260
  • 5
  • 22
  • 46
  • Duplicate of http://stackoverflow.com/questions/4020796/finding-the-max-value-of-an-attribute-in-an-array-of-objects please see it for solution – user3511851 Apr 08 '14 at 22:48
  • maybe my problem would be i'm new to json, and i think i could figure out the code if it was a javascript array. i'm writing code in the meantime to see if i can figure it out on my own. – Les Paul Apr 08 '14 at 22:49
  • 1
    @LesPaul - JSON is just a text format for expressing some javascript data structures. Once you call `JSON.parse()` on the JSON, it's just regular javascript. – jfriend00 Apr 08 '14 at 22:50
  • For future reference, anyone who wants to try to load an external JSON file into a variable check out here: http://stackoverflow.com/questions/2177548/load-json-into-variable – Les Paul Apr 09 '14 at 03:38

12 Answers12

30

Just cycle through the array, and keep track of the max as you go:

function getMax(arr, prop) {
    var max;
    for (var i=0 ; i<arr.length ; i++) {
        if (max == null || parseInt(arr[i][prop]) > parseInt(max[prop]))
            max = arr[i];
    }
    return max;
}

Usage is like:

var maxPpg = getMax(arr, "ppg");
console.log(maxPpg.player + " - " + maxPpg.team);

Fiddle demo

Edit

You can also use the Javascript "sort" method to get the top n values:

function getTopN(arr, prop, n) {
    // clone before sorting, to preserve the original array
    var clone = arr.slice(0); 

    // sort descending
    clone.sort(function(x, y) {
        if (x[prop] == y[prop]) return 0;
        else if (parseInt(x[prop]) < parseInt(y[prop])) return 1;
        else return -1;
    });

    return clone.slice(0, n || 1);
}

Usage:

var topScorers = getTopN(arr, "ppg", 2);
topScorers.forEach(function(item, index) {
    console.log("#" + (index+1) + ": " + item.player);
});

Fiddle demo

Community
  • 1
  • 1
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • This works when I have the array as a variable within the JavaScript function, but when I have arr as: var arr = $.getJSON(file); then it doesn't work. – Les Paul Apr 08 '14 at 23:39
  • @LesPaul sounds like an async problem? You have to use a callback, like `$.getJSON(function(arr) { var top2 = getTopN(arr, "ppg", 2); });` – McGarnagle Apr 08 '14 at 23:45
  • For future reference, anyone who wants to try to load an external JSON file into a variable check out here: http://stackoverflow.com/questions/2177548/load-json-into-variable – Les Paul Apr 09 '14 at 03:39
  • Now that I have paid more attention to the results in the console, I see that I do not get the players I am supposed to as the top scorers. For instance, I should be getting Kevin Durant (32.1) but I get Chris Kaman as the top scorer. I could easily fix this if CK was the lowest scorer but he's not....he's square in the middle. – Les Paul Apr 10 '14 at 02:50
  • 1
    @LesPaul ah, I think I see the problem. The values in the JSON are strings, so they're being compared as strings. Using `parseInt` on the values should fix this. I've updated above. – McGarnagle Apr 10 '14 at 05:39
  • change parseInt to parseFloat for decimal values. – Neelam May 23 '17 at 11:02
7

I found the following approach very neat:

arr.sort( 
  function(a, b) {
     return parseFloat(b['ppg']) - parseFloat(a['ppg']);
  }
)[0]['player']

Demo in snippet:

var arr =[
{
    "player" : "Andre Drummond",
    "team" : "Detroit Pistons",
    "ppg" : "15.4",
    "rpg" : "11.6",
    "apg" : "2.4",
    "bpg" : "1.6",
    "spg" : "0.8",
    "3pg" : "0.1"
},
{
    "player" : "Anthony Davis",
    "team" : "New Orleans Pelicans",
    "ppg" : "16.4",
    "rpg" : "13.6",
    "apg" : "2.6",
    "bpg" : "3.5",
    "spg" : "1.2",
    "3pg" : "0.1"
},
{
    "player" : "Carmelo Anthony",
    "team" : "New York Knicks",
    "ppg" : "27.4",
    "rpg" : "5.4",
    "apg" : "4.5",
    "bpg" : "1.1",
    "spg" : "1.5",
    "3pg" : "1.6"
}
]
console.log(
arr.sort( 
    function(a, b) {
       return parseFloat(b['ppg']) - parseFloat(a['ppg']);
    }
    )[0]['player']
);

First, I sort the array in descending order, then I choose the first element which contains the max value. In the code, I found the player who has the max ppg value. Hope this helps!

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Enayat
  • 3,904
  • 1
  • 33
  • 47
4

This should work:

var highestValue = 0; //keep track of highest value

//loop through array of objects
for (var i=0, len = ary.length; i<len; i++) {
  var value = Number(ary[i]["ppg"]);
  if (value > highestValue) {
      highestValue = value;
  }
}
Akinkunle Allen
  • 1,299
  • 12
  • 19
2

You might find this sortByAttribute function useful. Just pass in the attribute by string you're looking to sort it by, and it'll return whatever object has the max value for the specific attribute you're looking for. It'll still return the whole array, just sorted ascending by the property you specified.

var myArr = [
    {
        "player" : "Andre Drummond",
        "team" : "Detroit Pistons",
        "ppg" : "15.4",
        "rpg" : "11.6",
        "apg" : "2.4",
        "bpg" : "1.6",
        "spg" : "0.8",
        "3pg" : "0.1"
    },
    {
        "player" : "Anthony Davis",
        "team" : "New Orleans Pelicans",
        "ppg" : "16.4",
        "rpg" : "13.6",
        "apg" : "2.6",
        "bpg" : "3.5",
        "spg" : "1.2",
        "3pg" : "0.1"
    },
    {
        "player" : "Carmelo Anthony",
        "team" : "New York Knicks",
        "ppg" : "27.4",
        "rpg" : "5.4",
        "apg" : "4.5",
        "bpg" : "1.1",
        "spg" : "1.5",
        "3pg" : "1.6"
    }
  ]


function sortByAttribue(arr, attribute) {
  return arr.sort(function(a,b) { 
    return a[attribute] < b[attribute];
  });
}

sortByAttribue(myArr, "3pg") // returns Carmelo Anthony first
sortByAttribue(myArr, "bpg") // returns Anthony Davis first
BenR
  • 2,791
  • 3
  • 26
  • 36
  • This almost works. Whatever the first sortByAttribute function returns, that's the value I get for both sortByAttributes in both Firefox's and Chrome's console. So if I have "3pg" as the value passed in the first sortByAttribute function, I get "Carmelo Anthony" first for both sortByAttribute functions. If I have "bpg" as the value passed in the first sortByAttribute function, I get "Anthony Davis" first for both sortByAttribute functions. – Les Paul Apr 08 '14 at 23:57
2
function getMaxOfJson(jsonalreadyparsed, property) {
    var max = null;
    for (var i=0 ; i<jsonalreadyparsed.length ; i++) {

            if(max == null){

                max = jsonalreadyparsed[i][property];

            } else {

            if (parseFloat(jsonalreadyparsed[i][property]) > max){

                max = jsonalreadyparsed[i][property];

            }

        }

    }
    return max;
}

This works for me.

jwriteclub
  • 1,604
  • 1
  • 17
  • 33
Junior
  • 1,007
  • 4
  • 16
  • 26
1

This will allow you to choose what stat you want and what information you want back.

http://jsbin.com/tudegofa/1/edit

data => is the array

stat => is the stat you want to sort by

info => is an array of properties you want returned.

function getValues (data, stat, info)
{
  var selectedValues = data.map(function(x) {
    return parseFloat(x[stat]);
  })

  var i = selectedValues.indexOf(Math.max.apply(Math, selectedValues));

  var result = {};
  info.forEach(function(x) {
      result[x] = test[i][x];
  })
  return result;
}

var myData = '';
$.getJSON('/url/to/grab/json', function(data) {

  myData = data;

});

getValues(myData, "bpg", ["player","team"]);

//[object Object] {
//  player: "Anthony Davis",
//  team: "New Orleans Pelicans"
// }
KingKongFrog
  • 13,946
  • 21
  • 75
  • 124
1

function that's looking for item with the specific property'x maximum:

function getMax(array, propName) {
    var max = 0;
    var maxItem = null;
    for(var i=0; i<array.length; i++) {
        var item = array[i];
        if(item[propName] > max) {
            max = item[propName];
            maxItem = item;
        }
    }

    return maxItem;
}

usage:

$(document).ready(function() {
    $('#getMaxBtn').click(function() {
        var max = getMax(jsonArray, 'ppg');

        alert(max.player);
    });
});
Mr. Pumpkin
  • 6,212
  • 6
  • 44
  • 60
1

Simplicity thanks you in the long run.

function getMaxValueByAttribute(arr, attr) {
    var max = "-99999999999";
    arr.forEach(function (member, index) {
            // console.log(member, index);
            if (member.hasOwnProperty(attr) && parseFloat(member[attr]) > parseFloat(max)) {
                max = member[attr];
                // console.log("Max now: " + max);
            }
        });
    return max;
    }

Then use it like:

var result = getMaxValueByAttribute(arr, "ppg");
// result = "27.4"
kmonsoor
  • 7,600
  • 7
  • 41
  • 55
1

You can do it by lodash so easily.

var players = [{
    "player": "Andre Drummond",
    "team": "Detroit Pistons",
    "ppg": "15.4",
    "rpg": "11.6",
    "apg": "2.4",
    "bpg": "1.6",
    "spg": "0.8",
    "3pg": "0.1"
  },
  {
    "player": "Anthony Davis",
    "team": "New Orleans Pelicans",
    "ppg": "16.4",
    "rpg": "13.6",
    "apg": "2.6",
    "bpg": "3.5",
    "spg": "1.2",
    "3pg": "0.1"
  },
  {
    "player": "Carmelo Anthony",
    "team": "New York Knicks",
    "ppg": "27.4",
    "rpg": "5.4",
    "apg": "4.5",
    "bpg": "1.1",
    "spg": "1.5",
    "3pg": "1.6"
  }
];

var topscorer = _
  .chain(players)
  .sortBy('ppg')
  .reverse()
  .map(function(o) {
    return 'Top scorer: ' + o.player + ' - ' + o.team;
  })
  .head()
  .value();

console.log(topscorer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.min.js"></script>

Or even shorter:

var players = [{
    "player": "Andre Drummond",
    "team": "Detroit Pistons",
    "ppg": "15.4",
    "rpg": "11.6",
    "apg": "2.4",
    "bpg": "1.6",
    "spg": "0.8",
    "3pg": "0.1"
  },
  {
    "player": "Anthony Davis",
    "team": "New Orleans Pelicans",
    "ppg": "16.4",
    "rpg": "13.6",
    "apg": "2.6",
    "bpg": "3.5",
    "spg": "1.2",
    "3pg": "0.1"
  },
  {
    "player": "Carmelo Anthony",
    "team": "New York Knicks",
    "ppg": "27.4",
    "rpg": "5.4",
    "apg": "4.5",
    "bpg": "1.1",
    "spg": "1.5",
    "3pg": "1.6"
  }
];
console.log(_.maxBy(players, 'ppg').player);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
1

My solution here. Remember to use == instead of === to compare a number with a string.

const getMax = (arr, prop) => {
  const tmp = arr.map(x => x[prop]);
  const max = Math.max(...tmp);
  return arr.filter(x => x[prop] == max);
}

getMax(myArr,"bpg")

One line version:

myArr.filter( x => x["bpg"] == Math.max(...myArr.map(x => x["bpg"])) )
Juan
  • 39
  • 1
  • 9
1

the more simple:

const players =                                           
  [ { player: 'Andre Drummond',  team: 'Detroit Pistons',      ppg: '15.4', rpg: '11.6', apg: '2.4', bpg: '1.6', spg: '0.8', '3pg': '0.1' } 
  , { player: 'Anthony Davis',   team: 'New Orleans Pelicans', ppg: '16.4', rpg: '13.6', apg: '2.6', bpg: '3.5', spg: '1.2', '3pg': '0.1' } 
  , { player: 'Carmelo Anthony', team: 'New York Knicks',      ppg: '27.4', rpg: '5.4',  apg: '4.5', bpg: '1.1', spg: '1.5', '3pg': '1.6' } 
  ] 

const getPlayerMax_on = cod => players.reduce((a,c)=>((+a[cod])<(+c[cod]))?c:a)

const maxOn_ppg = getPlayerMax_on('ppg')

console.log( maxOn_ppg.player, maxOn_ppg.team, maxOn_ppg.ppg )
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

Lodash MaxBy

e.g.

var players = [{
     "name": "marvin",
     "age": "21"
  },
  {
    "name": "Lucy",
    "age": "26"
  },
  {
    "name": "james",
    "age": "21"
  }
];

maxBy(Players, 'age')

if its a raw json object i.e

maxBy(JSON.parse(Players), 'age')

=> {"name": "Lucy","age": "26"},

You can even return just the age i.e. maxBy(Players, 'age').age

=> 26

SamiElk
  • 2,272
  • 7
  • 20