You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对含重复值的数组排名并保留原数组顺序?

实现保留原顺序的重复值数组排名

首先明确需求:给包含重复值的数组生成排名,要求重复元素对应相同排名,且排名结果保留原数组的元素顺序,几个典型示例如下:

  • 输入数组 (6,4,7,12,7) → 预期排名 (2,1,3,4,3)
  • 输入数组 (12,17,5,27,5) → 预期排名 (2,3,1,4,1)
  • 输入数组 (1,1,4,6) → 预期排名 (1,1,2,3)

你提供的代码存在的问题

这段代码无法正确实现需求,核心问题出在重复元素的处理上:
当你用sort()对原数组排序后,重复元素会保留各自的索引(比如输入[12,17,5,27,5]排序后是[5,5,12,17,27]),原数组中第二个5会匹配到排序数组里索引为1的位置,最终输出排名是1+1=2,但我们需要的是和第一个5相同的排名1。

简单说,这段代码会给重复元素分配不同的排名,不符合需求。

正确的实现方法

我们可以通过“建立值与排名的映射表”来解决这个问题,步骤如下:

  1. 对原数组去重后排序,得到一个无重复的有序数组
  2. 为这个有序数组创建“元素值→对应排名”的映射(排名从1开始)
  3. 遍历原数组,直接通过映射表获取每个元素的排名,既保留原顺序,又保证重复元素同排名

代码示例

$values = array(12,17,5,27,5);

// 1. 去重并排序,得到无重复的有序数组
$uniqueSorted = array_unique($values);
sort($uniqueSorted);

// 2. 建立元素值到排名的映射(排名从1开始)
// 用range生成从1到数组长度的排名序列,和有序数组组合成映射
$rankMap = array_combine($uniqueSorted, range(1, count($uniqueSorted)));

// 3. 遍历原数组,获取每个元素的排名
$ranks = [];
foreach ($values as $value) {
    $currentRank = $rankMap[$value];
    $ranks[] = $currentRank;
    echo $value . ' has rank: ' . $currentRank . '<br>';
}

// 输出最终排名数组,和预期一致
print_r($ranks); // 输出:Array ( [0] => 2 [1] => 3 [2] => 1 [3] => 4 [4] => 1 )

代码验证

拿示例数组(6,4,7,12,7)测试:

  • 去重排序后得到[4,6,7,12]
  • 映射表为[4=>1, 6=>2,7=>3,12=>4]
  • 遍历原数组得到排名[2,1,3,4,3],完全符合预期。

优势说明

这种方法比嵌套循环的效率更高(尤其是处理大数组时),而且逻辑清晰,能完美满足“重复元素同排名+保留原顺序”的需求。

内容的提问来源于stack exchange,提问作者Lord Null

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:14:49