PHP模拟Excel RANK函数:并列同排名与名次跳跃算法
在数据处理场景中,常需使用Excel的RANK函数获取包含并列项的名次表,例如得分序列 195,180,180,161 对应的结果为 1,2,2,4(跳过3号位)。本文将通过PHP原生代码实现该逻辑,并给出可直接复用的函数集合。
原理概述
要实现“并列同排名,后一排名自动顺延跳过”的效果,可以依据以下公式计算每个元素的名次:
名次 = 总元素数量 - (小于当前值的元素数量) - (与当前值相等的元素数量) + 1
以总分序列 [195, 180, 180, 161] 为例:
- 195:比它小的有3个(180,180,161),重复1次 → 4 - 3 - 1 + 1 = 1
- 180(两个):比它小的有1个(161),重复2次 → 4 - 1 - 2 + 1 = 2
- 161:比它小的有0个,重复1次 → 4 - 0 - 1 + 1 = 4
最终得到名次数组 [1, 2, 2, 4],与Excel的默认RANK.EQ表现一致。
准备工作
确保运行环境具备 PHP 5.4+ (因使用了类型声明 array $array)。无需额外依赖或数据库连接,所有计算基于纯数组操作即可。
第1步:定义辅助函数
需要两个子函数分别统计“更小值数量”和“重复出现次数”,以便主函数统一调用:
// 统计数组中严格小于指定值的元素个数
function countSmallerValues($value, array $array): int {
return array_reduce(
$array,
fn($carry, $val) => ($val < $value) ? $carry + 1 : $carry,
0
);
}
// 获取指定值在数组中的出现次数
function countRepeatedValues($value, array $array): int {
return array_sum(array_map(fn($v) => $v === $value ? 1 : 0, $array));
}
第2步:构建核心排名函数
遍历输入数组,依次套用排名公式返回对应位置的名次列表:
/**
* 模拟 Excel RANK 行为:并列同名次,后续名次自动跳跃
*/
function excelLikeRank(array $scores): array {
$total = count($scores);
$ranks = [];
foreach ($scores as $score) {
$lessThan = countSmallerValues($score, $scores);
$duplicates = countRepeatedValues($score, $scores);
// 按公式得出该名次的实际值
$ranks[] = $total - $lessThan - $duplicates + 1;
}
return $ranks;
}
实际应用示例
调用上述函数并打印结果,验证输出是否符合预期:
$scores = [195, 180, 180, 161];
$ranks = excelLikeRank($scores);
print_r($ranks); // 输出: Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 4 )
若需要将名次数组写回关联结构(如绑定 ID),可合并索引信息:
$data = [
['id' => 1, 'score' => 195],
['id' => 2, 'score' => 180],
['id' => 3, 'score' => 180],
['id' => 4, 'score' => 161]
];
$rawScores = array_column($data, 'score');
$final = array_map(
fn($row, $rank) => [$row['id'] => $rank],
$data,
excelLikeRank($rawScores)
);
print_r(array_combine(array_column($data,'id'), $final));
完成判断标准
- 相同分数的名次完全一致;
- 下一名次紧接已占用最大值并跳过中间空缺。
简要总结
以上就是 PHP 模拟 Excel 中 RANK 函数并列同排名及名次跳跃的详细方法。通过拆分计数逻辑并在循环内组合公式,能稳定产出符合直觉的成绩/积分排名表。更多关于此类基础排序算法的实现技巧与优化实践请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









