ES6 查找对象数组中的最大数

6

我有以下数据

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

现在我正在尝试获取具有最高数量的对象。 我已经尝试使用reduce,如下所示。
let highest = shots.reduce((max, shot) => {
    return shot.amount > max ? shot : max, 0
});

但我总是得到最低分,你有什么想法可能是我错过了什么吗?

谢谢。


1
尝试:shots.reduce((max, shot) => shot.amount > max.amount ? shot : max) - CD..
你需要从reduce返回值。此外,你应该为reduce设置一个初始值。 - Reason
你的数值也可以是负数吗? - gurvinder372
7个回答

18

简洁的2行解决方案 :)

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

更新

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

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

我喜欢那个!聪明。 - Miguel Stevens
简洁而优雅,找到对象的简单方法如下:const highest = shots.find(e => e.amount === highestAmount) - scagood
唯一的问题是,这里我们只得到了最高金额,而不是对象本身,对吧? - Miguel Stevens
是的,只有最高金额。但如果你需要这个对象,我想你应该重新考虑和思考你正在做什么(你想要实现什么)。想象一下,如果你有更多相同金额(最高)的对象。你真的想要获取所有的吗?如果你这样做:var highestShots = shots.filter(shot => shot.amount === highestAmount) 就可以了。 - Cristian S.
请注意,对于任何中等大小的数组,Math.max(...amounts)可能会导致“超出最大调用堆栈大小”的错误。 - Colin D

15

这里有两个问题,第一个是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]

1
此代码在所有负值下都会中断,因为将数字与未定义的内容进行比较。例如,-4 > undefined 是错误的,而在这种情况下,-4 将是最大的数字。因此,这不是最好的答案。同时,您还损失了 id 属性。 - Rogier Slag
1
很抱歉,但对于负数,这仍然会出错。 -4> 0 => false,因此如果数组中唯一的条目具有金额-4,则您的代码将返回0 - Rogier Slag
@RogierSlag - 向您致敬 再次感谢,已更改为最小安全整数。 - scagood
1
接近了但还没到位 ;) 假设数组中只有一个元素,其数量为Number.MIN_SAFE_INTEGER。上面的代码片段将返回种子而不是实际数字。因此,使用此方法会丢失该对象的ID。此外,这也取决于函数的要求:如果两个数字相等且都最高,应该返回第一个还是最后一个? - Rogier Slag
2
@RogierSlag - 这次交流让我很开心,谢谢!希望我现在已经明白了! - scagood

2

请尝试以下方法:

更新

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

2

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

  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的情况。

1
你可以检查两个项目的amount属性,返回amount值最大的那个项目。
let highest = shots.reduce((a, b) => a.amount > b.amount ? a : b);

对于相同数量,只能获取第一个对象的相同数量。
它不能用于空数组。
如果您喜欢所有具有相同最高数量的对象,则可以使用两个条件来缩小数组。
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);

当对象具有两个以上的项目时,这不起作用,我是对的吗? - Brian
@BrianVanegasParra,那么您需要采用不同的方法并使用数组作为结果集。请参见编辑。 - Nina Scholz
你的答案很好,但是我的问题没有被上下文所解释。 - Brian

0
你可以使用这段代码。它将简单地返回最高金额。
Math.max.apply(Math,shots.map((shot)=>{return shot.amount;}));

1
他们正在寻找对象,而不仅仅是数量,但需要一个简洁的解决方案。 - scagood

0

有几个错误

  • 返回 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 );

编辑

如果需要返回整个对象,则初始化器应该是一个带有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 );

谢谢您的回答,我想要返回拥有最高金额的完整对象,这样做不会只返回金额吗? - Miguel Stevens
谢谢!上面已经有一个答案了,但我相信你的也可以! - Miguel Stevens

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