关于排行榜如果分数相同,得分相同时间早的排在前面的操作。

之前刷到一个博主的文章,分享下自己想法
原文章地址

第一种方式

根据REDIS的默认规则,如果具有相同分数值的成员按字典序的逆序(reverse lexicographical order)排列

//接收命令行参数
$key= $argv[1]; 
$score= $argv[2]; 

//Redis存储
if (!extension_loaded('redis')) {
    die('Please install the phpredis extension.');
}
//这种方式缺点就是你必须知道这次排名有多少。比如说你已经知道这次排名有26个,那么就直接从第26个开始,然后倒序排列。假设分数为100,第一个100为 “key+Z”=keyZ,第二个为 “key+Y”=keyY
$redis=new REDIS();
$redis->connect('192.168.70.3',6379);
$redis->Zadd('rank',$score,$key);
$members = $redis->zRevRange('rank', 0, -1, true);
print_r($members);
$redis->close();

关于排行版如果分数相同,时间早的排在前面的操作。

第二种方式

位运算+时间戳(活动结束时间-得分时间)

//根据整形进行位运算,加上活动结束时间减去当前时间(越早减得分数越高),这种方式要注意当前系统是多少位在进行位运算,不然超出之后会出错。

$now_timestamp= time(); //当前得分时间
$activity_timestamp= strtotime("2024-08-30 15:10:37");//活动结束时间

//接收命令行参数
$key= $argv[1]; 
$score= $argv[2]; 

//Redis存储
if (!extension_loaded('redis')) {
    die('Please install the phpredis extension.');
}

$score=$score << 32;
$score+=$activity_timestamp-$now_timestamp;

$redis=new REDIS();
$redis->connect('192.168.70.3',6379);
$redis->Zadd('rank',$score,$key);
$members = $redis->zRevRange('rank', 0, -1, true);
print_r($members);
//还原分数
foreach($members as $k=>$v){
    $v_shifted = $v >> 32;
    // 输出结果
    echo $k . ':' . $v_shifted . PHP_EOL;
}
$redis->close();

关于排行版如果分数相同,时间早的排在前面的操作。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3
Jyunwaa

什么时候开始流行面向 Redis 编程了。


<?php
declare(strict_types=1);

class Player
{
    public function __construct(public int $id, public int $score, public int $timestamp)
    {
    }
}

class ScoreRank extends SplMaxHeap
{
    protected function compare(mixed $value1, mixed $value2): int
    {
        return match (true) {
            $value1->score > $value2->score => 1,
            $value1->score < $value2->score => -1,
            default                         => $value2->timestamp <=> $value1->timestamp
        };
    }
}

$score_rank = new ScoreRank();
$score_rank->insert(new Player(1, 98, 1723292086));
$score_rank->insert(new Player(2, 98, 1723292087));
$score_rank->insert(new Player(3, 97, 1723292084));
$score_rank->insert(new Player(4, 96, 1723292085));
$score_rank->insert(new Player(5, 98, 1723292087));

foreach ($score_rank as $player) {
    print_r($player);
}

// Player Object
// (
//     [id] => 1
//     [score] => 98
//     [timestamp] => 1723292086
// )
// Player Object
// (
//     [id] => 5
//     [score] => 98
//     [timestamp] => 1723292087
// )
// Player Object
// (
//     [id] => 2
//     [score] => 98
//     [timestamp] => 1723292087
// )
// Player Object
// (
//     [id] => 3
//     [score] => 97
//     [timestamp] => 1723292084
// )
// Player Object
// (
//     [id] => 4
//     [score] => 96
//     [timestamp] => 1723292085
// )
6个月前 评论

mysql100万数据阁下又该如何应对

6个月前 评论
吃橘子的汤圆 (楼主) 6个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!