【问题标题】:How do i use Math.max with an array of objects?如何将 Math.max 与对象数组一起使用?
【发布时间】:2016-04-17 10:35:42
【问题描述】:

我想在一个对象数组中选择最大的数, 所以举个例子,我想得到拥有最大数字的x属性(在这个例子中,maximum应该是200):

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

//does not work:
var maximum = Math.max.apply(Math,myArr.x);

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您必须自己从对象中提取属性:

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

    它使用.map() 遍历数组的元素并返回“x”属性的值。然后将该结果数组作为参数传递给Math.max()

    现在=> 函数已广泛使用,它会更短一些:

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

    当然,仍然在做几乎完全相同的事情。

    【讨论】:

    • 很久以来,显然,那时我接受了我更容易理解的答案(现在接受的答案),但从赞成的数量来看,您的解决方案是首选。你能解释一下为什么吗?
    • @Taurus 好吧,我想这是因为它更简洁。然而,它并没有做任何根本不同的事情。
    【解决方案2】:

    还有一种方式,我觉得更美。通过使用传播:

    Math.max(...array.map((i) => i.x));
    

    【讨论】:

      【解决方案3】:
      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);
      

      先降序sort by key value再获取第一个对象的x属性

      【讨论】:

      • "作为使用Math.max的替代方法"... :)
      • @Andy 是的,我的意思是作为替代方案 :) 如果值不是数字(以防万一需要)也可以工作
      【解决方案4】:

      如果你想用老式的方式来做:

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

      此函数将对象数组作为第一个参数,将一个键作为第二个参数。它遍历数组并返回为给定键找到的最大值。

      在你的情况下,你可以这样称呼它:

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

      请注意,与 Math.max 不同,这对于一个(或多个)对象没有定义该键的情况具有弹性,因此:

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

      将返回300,而Math.max 返回NaN(至少在谷歌浏览器上)。最坏的情况(所有对象都没有定义键),arrayMax 函数返回-Infintity

      如果你想返回具有最大值的对象而不是简单地返回值,你可以很容易地修改函数来做到这一点:

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

      【讨论】:

        【解决方案5】:

        你需要将map对象数组转成数字数组:

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

        【讨论】:

        • o 代表对象还是我独立改变那个“o”?
        • 只是一个参数名。把它改成你想要的,
        【解决方案6】:

        你最好不要使用 Math.max。

        MDN 警告说,如果数组中的元素过多,.apply 可能不起作用。我不确定“太多”是什么意思。

        如果您想安全,请使用以下内容:

        const maxReduced = myArr
          .map(obj => {
            return obj.x;
          })
          .reduce((a, b) => (a.x > b.x ? a : b));
        

        MDN Warning

        但是,传播 (...) 和应用都将失败或返回 如果数组有太多元素,则结果错误,因为它们试图 将数组元素作为函数参数传递。请参阅使用 apply 和 内置函数以获取更多详细信息。减少解决方案没有 这个问题。

        【讨论】:

          【解决方案7】:
          const maximum = myArr.reduce((s, obj)=>{
            return Math.max(s, obj.x)
          }, 0)
          

          原因 -

          https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max 如果数组元素过多,spread (...) 和 apply 都将失败或返回错误结果,因为它们试图将数组元素作为函数参数传递。有关更多详细信息,请参阅使用 apply 和内置函数。 reduce方案没有这个问题。

          【讨论】:

            猜你喜欢
            • 2020-09-24
            • 1970-01-01
            • 1970-01-01
            • 2020-10-13
            • 2016-04-11
            • 1970-01-01
            • 1970-01-01
            • 2013-03-03
            • 2016-11-15
            相关资源
            最近更新 更多