【问题标题】:ES6 Find the maximum number of an array of objectsES6 查找对象数组的最大数量
【发布时间】:2018-02-14 12:06:11
【问题描述】:

我有以下数据

shots = [
    {id: 1, amount: 2},
    {id: 2, amount: 4}
]

现在我正在尝试获取数量最多的对象

我尝试过如下使用reduce

let highest = shots.reduce((max, shot) => {
    return shot.amount > max ? shot : max, 0
});

但我总是得到最低的数字。 知道我可能缺少什么吗?

谢谢。

【问题讨论】:

  • 试试:shots.reduce((max, shot) => shot.amount > max.amount ? shot : max)
  • 你需要从reduce返回值。另外,你应该有一个 reduce 的初始值
  • 你的金额也可以有负值吗?

标签: javascript ecmascript-6


【解决方案1】:

更清洁的 2 行解决方案 :)

const amounts = shots.map((a) => a.amount)
const highestAmount = Math.max(...amounts);

更新

上面的代码将返回最高金额。如果要获取包含它的对象,您将面临许多对象包含最高值的可能性。所以你需要filter

const highestShots = shots.filter(shot => shot.amount === highestAmount)

【讨论】:

  • 我喜欢这样!智能
  • 漂亮而优雅,找到对象的简单方法是:const highest = shots.find(e => e.amount === highestAmount)
  • 唯一的问题是我们只得到最高的金额,而不是对象本身,对吧?
  • 是的,只有最高金额。但是,如果您需要该对象,我想您应该重新考虑并重新考虑您正在做的事情(您要实现的目标)的复杂性。想象一下,如果您有更多相同数量(最高)的对象。你真的想得到所有这些吗?如果你这样做:var highestShots = shots.filter(shot => shot.amount === highestAmount) 会这样做。
  • 请注意,对于任何中等大小的数组,Math.max(...amounts) 可能会导致“超出最大调用堆栈大小”错误
【解决方案2】:

这里有两个问题,第一个是reduce需要返回值。第二个是您将数字与对象进行比较。

因此,我认为你需要这样的东西:

// This will return the object with the highest amount.
let highest = shots.reduce((max, shot) => {
    return shot.amount >= max.amount ? shot : max;
}, {
    // The assumption here is that no amount is lower than a Double-precision float can go.
    amount: Number.MIN_SAFE_INTEGER
});

// So, we can convert the object to the amount like so:
highest = highest.amount;

编辑:

一个干净的短衬里看起来像这样:

const highest = shots.sort((a, b) => b.amount - a.amount)[0]

【讨论】:

  • 由于您将一个数字与未定义的数字进行比较,因此该值会破坏所有负值。 -4 > undefined 例如是假的,而在这种情况下,-4 将是最大的数字。因此,这并不是最好的答案。在此过程中,您也会丢失 id 属性
  • 很抱歉,但是对于负数,这仍然会中断。 -4 > 0 => false 因此,如果数组中唯一的条目数量为 -4,您的代码将返回 0
  • @RogierSlag - 向你致敬再次感谢,已更改为 min safe int
  • 正在关闭但还没有;)想象一下数组中有一个项目,其数量是数字。 MIN_SAFE_INTEGER。上面的代码 sn-p 将返回种子而不是实际数字。因此,使用此方法您会丢失该对象的 id。还取决于函数的要求:两个数字是否相等且都最高,您应该返回第一个还是最后一个?
  • @RogierSlag - 这次谈话让我很开心,谢谢!希望我现在明白了!
【解决方案3】:

试试这个:

更新

let highest = shots.reduce((max, shot) => {
  return shot.amount > max.amount ? shot : max
}, {amount:0});

【讨论】:

    【解决方案4】:

    很遗憾,这里的大多数答案并没有正确考虑所有情况

    1. 种子值关闭
    2. 在不同类型之间进行比较

    要正确处理负值,您必须使用 -Infinity 播种

    再将该点的最大值与新值进行比较

    你会得到以下内容:

    highest = shots.reduce((max, current) => current.amount >= max.amount ? current : max, {amount: -Infinity})
    

    你可以用这个来测试

    shots = [
        {id: 1, amount: -2},
        {id: 2, amount: -4},
        {id: 3, amount: -4},
        {id: 4, amount: -5},
    ]
    highest = shots.reduce((max, current) => current.amount >= max.amount ? current : max, {amount: -Infinity}) // Returns id 1, amount -2
    
    shots = [
        {id: 1, amount: 2},
        {id: 2, amount: 4},
        {id: 3, amount: 4},
        {id: 4, amount: 5},
    ]
    highest = shots.reduce((max, current) => current.amount > max.amount ? current : max, {amount: -Infinity}) // Returns id 4 amount 5
    

    请注意,如果数组为空,您将得到{amount: -Infinity} 的值,因此您可能需要处理reduce 之前shots.length === 0 的情况

    【讨论】:

      【解决方案5】:

      您可以检查两个项目的金额属性并返回金额最大的项目。

      let highest = shots.reduce((a, b) => a.amount > b.amount ? a : b);
      

      对于相同数量,您只获得相同数量的第一个对象。

      它不适用于空数组。

      如果您喜欢所有具有相同最高amount 的对象,您可以使用两个条件来减少数组。

      let highest = shots.reduce((r, o) => {
              if (!r || o.amount > r[0].amount) return [o];
              if (o.amount === r[0].amount) r.push(o);
              return r;
          }, undefined);
      

      【讨论】:

      • 当对象有两个以上的项目时这不起作用,我是对的?
      • @BrianVanegasParra,那么您需要一种不同的方法和一个数组作为结果集。请参阅编辑。
      • 你的回答很好,我有没有上下文化的问题
      【解决方案6】:

      有几个错误

      • 返回shot.amount 而不是shot
      • 只返回比较后的值

      终于

      shots.reduce((max, shot) => 
          shot.amount > max ? shot.amount : max, 0);
      

      演示

      var shots = [
          {id: 1, amount: 2},
          {id: 2, amount: 4}
      ];
      var output = shots.reduce((max, shot) => 
          shot.amount > max ? shot.amount : max, 0);
      console.log( output );

      编辑

      如果必须返回整个对象,那么initializer应该是一个具有amount属性的对象

      var shots = [
          {id: 1, amount: 2},
          {id: 2, amount: 4} ]; 
      var output = shots.reduce((max, shot) => 
          shot.amount > max.amount ? shot : max , {amount:0}); 
      console.log( output );
      

      【讨论】:

      • 感谢您的回答,我想返回金额最高的完整对象,这不是只返回金额吗?
      • 谢谢!上面有一个答案,但我相信你的也可以!
      【解决方案7】:

      您可以使用此代码。它只会返回最高金额。

      Math.max.apply(Math,shots.map((shot)=>{return shot.amount;}));
      

      【讨论】:

      • 他们在寻找对象,不仅仅是数量,而是一个巧妙的解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-08
      • 2021-01-04
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      相关资源
      最近更新 更多