redis的集合是 无序、不重复的集合,如果一个抽奖系统只需要简单的从一堆数据里抽出一部分,那么redis就可以简单的实现
主要用到了SPOP(随机移除并返回集合中一个或多个元素) 和 SRANDMEMBER(随机返回集合中一个或多个元素)
package main
import (
"fmt"
"github.com/gomodule/redigo/redis"
)
// 简单抽奖
func main() {
var allPeople = []string{
"Tom",
"Jerry",
"Linda",
"John",
"Peter",
"Cooper",
"Amy",
"Bob",
"Luck",
}
var keyName = "lucky:1"
args := []interface{}{keyName}
for _, person := range allPeople {
args = append(args, person)
}
// sadd 存入 lucky:1
_, err := Redis().Do("sadd", args...)
defer Redis().Close()
if err != nil {
panic(err)
}
// 随机抽三个幸运用户
//SRANDMEMBER(随机返回集合中一个或多个元素)
lotteryResult := getLottery(keyName, 3)
fmt.Printf("三个幸运用户是:%v \n", lotteryResult)
// 分层抽,抽三次,每次抽,1,2,3 个人分别为1等奖,2等奖,3等奖,且一个人只能获得一种奖,不重复抽取
// SPOP(随机移除并返回集合中一个或多个元素)
noRepeatLottery := getNoRepeatLottery(keyName)
for i, strings := range noRepeatLottery {
fmt.Printf("%v等奖:%v \n", i+1, strings)
}
}
func getNoRepeatLottery(keyName string) [][]string {
var lotteryPeopleList [][]string
//先抽一个一等奖
reply, err := redis.Strings(Redis().Do("SPOP", keyName, 1))
if err != nil {
panic(err)
}
lotteryPeopleList = append(lotteryPeopleList, reply)
//抽两个二等奖
reply2, err := redis.Strings(Redis().Do("SPOP", keyName, 2))
if err != nil {
panic(err)
}
lotteryPeopleList = append(lotteryPeopleList, reply2)
//抽三个三等奖
reply3, err := redis.Strings(Redis().Do("SPOP", keyName, 3))
if err != nil {
panic(err)
}
lotteryPeopleList = append(lotteryPeopleList, reply3)
return lotteryPeopleList
}
func getLottery(keyName string, luckyPeopleCount int) []string {
//SRANDMEMBER(随机返回集合中一个或多个元素)
reply, err := redis.Strings(Redis().Do("SRANDMEMBER", keyName, luckyPeopleCount))
defer Redis().Close()
if err != nil {
panic(err)
}
return reply
}
func Redis() redis.Conn {
dial, err := redis.Dial("tcp", "127.0.0.1:6379")
if err != nil {
panic(err)
}
return dial
}