JavaScript 如何获取数组中数值最高的两个去重元素
两种可落地的实现方案
方案1:单循环O(n)高效实现(适配长数组场景)
这种方法不需要对整个数组排序,仅一次遍历就能拿到去重后的最大两个值,性能最优,和你现有写的indexOfMax循环逻辑兼容,可以直接扩展。
实现逻辑:
- 初始化两个变量
firstMax、secondMax,初始值设为-Infinity,分别记录第一大、第二大的数值 - 遍历数组每个元素时,跳过和已记录的最大值、第二大值相等的重复元素,再按大小关系更新两个变量:
- 当前元素比
firstMax大:原firstMax降级为secondMax,当前值更新为新的firstMax - 当前元素比
firstMax小、但比secondMax大:直接更新secondMax为当前值
- 当前元素比
- 遍历结束后过滤掉无效的初始值(适配数组没有两个不同元素的边界场景),返回结果数组
可直接运行的代码:
getTopTwoValues(arr) { let firstMax = -Infinity; let secondMax = -Infinity; if (!arr?.length) return []; for (let i = 0; i < arr.length; i++) { const currentVal = arr[i]; // 跳过重复值,避免同值占用第二大的位置 if (currentVal === firstMax || currentVal === secondMax) continue; if (currentVal > firstMax) { secondMax = firstMax; firstMax = currentVal; } else if (currentVal > secondMax) { secondMax = currentVal; } } // 清除未被赋值的初始值,比如数组只有一种元素的场景 return [firstMax, secondMax].filter(item => item !== -Infinity); }
针对你举的测试用例[1, 2, 3, 4, 3, 1, 0],运行后会得到[4, 3],完全符合预期。如果需要兼顾原有indexOfMax取索引的能力,完全可以在同一个循环里同时记录最大、第二大值的索引位置,不需要重复遍历数组。
方案2:简洁实现(适配短数组快速开发场景)
如果数组长度不大,不需要极致性能,可以用JS内置方法快速实现,代码逻辑简单易读:
getTopTwoValues(arr) { // 先对数组去重,再按降序排序,最后取前两位 return [...new Set(arr)].sort((a, b) => b - a).slice(0, 2); }
注意:这个方案内置的sort是O(n log n)时间复杂度,数组长度超过1000时性能会明显低于单循环方案,适合短数组的快速开发场景。
内容的提问来源于stack exchange,提问作者nejelo3022
相关产品推荐
相关产品推荐

