获取JSON数组中的最大值

23

我想创建一个JavaScript函数,该函数从外部JSON中的数组中获取信息,然后获取其中一个JSON变量的最大值(或前五个值)。 对于此示例,假设我想获取"value"为"ppg"的最大值。以下是数组的小样本:

[
{
    "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"
}
]

如何遍历数组以获取最大值,然后从该值获取“player”和“team”值是最佳方法?该页面将是交互式的,因为我将有一个下拉菜单栏,允许查看者选择除“player”和“team”之外的六个JSON值中的一个。提前致谢!


请参考 https://dev59.com/2W865IYBdhLWcg3wCp9A 中的解决方案。 - user3511851
也许我的问题在于我对 JSON 不熟悉,如果这是一个 JavaScript 数组,我认为我可以解决代码。我正在编写代码,看看能否自己解决它。 - Les Paul
1
@LesPaul - JSON只是一种文本格式,用于表示一些JavaScript数据结构。一旦您在JSON上调用JSON.parse(),它就变成了普通的JavaScript。 - jfriend00
供日后参考,任何想要尝试将外部JSON文件加载到变量中的人,请查看此处:https://dev59.com/93I95IYBdhLWcg3wvgh9 - Les Paul
12个回答

30

只需循环遍历数组,并在此过程中跟踪最大值:

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

使用方法如下:

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

演示链接

编辑

你也可以使用 JavaScript 的 "sort" 方法获取前 n 个最大值:

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

使用方法:

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

演示


当我将数组作为JavaScript函数内的变量时,它可以正常工作,但是当我将arr定义为:var arr = $.getJSON(file);时,它就无法工作了。 - Les Paul
@LesPaul听起来像是异步问题?你必须使用回调函数,例如$.getJSON(function(arr) { var top2 = getTopN(arr, "ppg", 2); }); - McGarnagle
供日后参考,任何想要尝试将外部JSON文件加载到变量中的人,请查看此处:https://dev59.com/93I95IYBdhLWcg3wvgh9 - Les Paul
现在我更加关注控制台中的结果,我发现我没有得到我应该得到的顶尖得分手。例如,我应该得到凯文·杜兰特(32.1),但我得到的是克里斯·卡曼作为最高得分手。如果CK是最低得分手,我可以很容易地解决这个问题,但他不是...他正好处于中间位置。 - Les Paul
1
@LesPaul 啊,我想我看出问题了。JSON中的值是字符串,因此它们被作为字符串进行比较。在值上使用parseInt应该可以解决这个问题。我已经进行了更新。 - McGarnagle
将 parseInt 改为 parseFloat 以处理小数值。 - Neelam

7

我觉得以下方法非常简洁:

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

片段中的演示:

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

首先,我将数组按降序排序,然后选择包含最大值的第一个元素。在代码中,我找到了具有最大ppg值的player。希望这能帮到你!


4

这应该可以工作:

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

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

这对我很有效。


2
你可能会发现这个sortByAttribute函数很有用。只需传入你想按其排序的属性字符串,它将返回具有特定属性最大值的任何对象。它仍然会返回整个数组,只是按照你指定的属性升序排序。
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

这几乎可以工作。无论第一个sortByAttribute函数返回什么,我在Firefox和Chrome控制台中都会得到相同的sortByAttributes值。因此,如果我将“3pg”作为传递给第一个sortByAttribute函数的值,则在两个sortByAttribute函数中,“Carmelo Anthony”将首先出现。如果我将“bpg”作为传递给第一个sortByAttribute函数的值,则在两个sortByAttribute函数中,“Anthony Davis”将首先出现。 - Les Paul

1

简单性长远来看是令人感激的。

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

然后像这样使用它:
var result = getMaxValueByAttribute(arr, "ppg");
// result = "27.4"

1

我的解决方案在这里。记得使用==而不是===来比较数字和字符串。

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

一行版本:

myArr.filter( x => x["bpg"] == Math.max(...myArr.map(x => x["bpg"])) )

1
你可以通过 lodash 轻松地完成它。

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>

甚至更短:

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>


1
越简单越好:

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 )


1

这将允许您选择想要的统计数据和想要返回的信息。

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

data => 数组

stat => 想要排序的统计量

info => 想要返回的属性数组。

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"
// }

我在console.log中得到了这个错误:TypeError: data.map不是一个函数 - Les Paul
你提到的数据是以数组的形式呈现的吗? - KingKongFrog
它如上所述。需要注意的是,它在外部JSON文件中。 - Les Paul
我添加了一些代码来展示如何将你的JSON传递到函数中。 - KingKongFrog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接