基于NextJS+Supabase的高尔夫分组抽签功能高效实现需求
高尔夫球会分组抽签功能实现方案
需求说明
- 总人数:支持4、6……最多32人(不支持5人)
- 每组人数:优先4人组(2对2组合),剩余人数按规则生成3人组
- 表格排序:3人组需排在表格顶部
- 数据来源:从Supabase筛选指定日期内确认参赛的会员,为每个会员添加随机数
rnd,得到结构为{name: "bill", rnd: 0.5565789}的会员数组
分组逻辑规则
- 总人数%4余3:生成1个3人组,其余为4人组
- 总人数%4余2:生成2个3人组,其余为4人组
- 总人数%4余1:生成3个3人组,其余为4人组
- 总人数%4余0:全部为4人组
高效代码实现
const date = await getLatestDate(); if (!date) throw new Error("未获取到有效日期"); const members = await getMembers(date); if (!members) throw new Error("未获取到会员数据"); // 筛选参赛会员并添加随机数(避免修改原对象) const playingMembers = members .filter(member => member.playing) .map(member => ({ ...member, rnd: Math.random() })); const totalPlayers = playingMembers.length; // 校验人数合法性 if (totalPlayers < 3 || totalPlayers === 5) { throw new Error("当前参赛人数不支持分组"); } // 按随机数排序,实现抽签效果 playingMembers.sort((a, b) => a.rnd - b.rnd); // 通过余数直接映射3人组数量,替代冗余条件判断 const threeMemberGroupCount = [0, 3, 2, 1][totalPlayers % 4]; const groups: Member[][] = []; let currentIndex = 0; // 先生成所有3人组,保证排在顶部 for (let i = 0; i < threeMemberGroupCount; i++) { groups.push(playingMembers.slice(currentIndex, currentIndex + 3)); currentIndex += 3; } // 生成剩余的4人组 while (currentIndex < totalPlayers) { groups.push(playingMembers.slice(currentIndex, currentIndex + 4)); currentIndex += 4; } // groups数组即为最终分组结果,可直接用于渲染表格
代码亮点
- 用
map替代forEach添加随机数,遵循函数式编程风格,避免修改原会员对象 - 利用数组索引映射余数与3人组数量的关系,省去繁琐的if/else分支
- 通过
slice批量截取生成分组,代码简洁高效且易维护 - 先处理3人组再处理4人组,自然满足3人组排在顶部的要求
内容的提问来源于stack exchange,提问作者SgtBilko
相关产品推荐
相关产品推荐

