基于JavaScript开发一个有趣的分组抽签小程序
作者:𝑺𝒉𝒊𝒉𝑯𝒔𝒊𝒏𝒈
前言
今天我要和大家分享一个非常有用的js算法:分组抽签。在团队合作开发中,经常需要将团队成员分组,来完成各自的任务。而抽签的方式自然是最公平、最简单的方法之一。
需求分析
在介绍具体的抽签算法之前,我们先来分析一下这个问题的需求。我们需要从团队成员列表中随机抽取若干人,并将这些人分配到不同的组中。那么,如何才能确保分组的公平性呢?
公平性的要求
首先,我们需要确保每个人只会被抽中一次,避免出现某个人被抽到多个组的情况。其次,我们需要尽可能地让每个组的人数相近,以确保各组的工作量基本相同。
算法设计思路
在满足上述需求的前提下,我们可以通过以下算法来进行分组抽签:
1.将团队成员列表随机排序。
2.根据分组的数量,计算每个组应该包含的人数,记为baseNum。
3.依次遍历团队成员列表,将每个人放入对应的组中。具体操作步骤如下:
- 如果该人已经被分配了组,直接跳过。
- 如果该人所在的组未满员,将其加入该组,并标记为已分组。
- 如果该人所在的组已满员,寻找下一个未满员的组,将其加入该组,并标记为已分组。如果没有未满员的组,则随机选择一个非自己所在组的未满员组,将其加入该组,并标记为已分组。
通过以上阐述可知,核心的算法思路是要随机排序、尽量平均分组并避免同一人多次参与。现在我们开始着手编写这个算法。
开始编码
随机排序
为了实现随机排序,我们可以先将团队成员数组进行浅拷贝,然后使用Array.sort()方法来进行排序,代码如下:
function shuffle(array) { const arr = [...array]; // 进行浅拷贝 for (let i = arr.length - 1; i > 0; i--) { // 遍历数组元素 const j = Math.floor(Math.random() * (i + 1)); // 生成随机下标 [arr[i], arr[j]] = [arr[j], arr[i]]; // 交换位置 } return arr; // 返回排序后的数组 }
该方法接受一个数组作为参数,返回乱序排列之后的新数组。
尽可能平均分组
为了实现尽量平均分组,我们可以使用Math.ceil()方法来向上取整,保证每个组的人数不少于baseNum。代码如下:
const team = ['张三', '李四', '王五', '赵六', '钱七', '孙八']; // 假设有6名成员 const groupNum = 3; // 定义需要抽几组 const baseNum = Math.ceil(team.length / groupNum); // 计算每组包含的人数 console.log(baseNum); // 输出2
避免同一人多次参与
为了避免同一个人多次参与分组,我们需要给已经分配了组的成员打上已分组的标记,这样在后续循环中就可以跳过已经分配了组的成员。代码如下:
const team = ['张三', '李四', '王五', '赵六', '钱七', '孙八']; // 团队成员数组 const groupNum = 3; // 分组数 const baseNum = Math.ceil(team.length / groupNum); // 计算每组需要包含多少人 const shuffledTeam = shuffle(team); // 乱序排列团队成员 let assignedCount = 0; // 计数器,记录已分配的人数 let groups = []; // 定义一个空数组,用来存放每个分组的成员 // 遍历随机排序后的团队成员列表,进行分组 shuffledTeam.forEach(member => { if (member.assigned) return; // 如果该成员已被分配,则跳过 for (let i = 0; i < groupNum; i++) { const group = groups[i] || []; // 如果当前分组未定义,则将其初始值设为空数组 if (group.length < baseNum && !group.includes(member)) { // 如果该分组未满员,并且该成员没有被分配到其他组内 group.push(member); // 将该成员加入当前分组 member.assigned = true; // 给该成员打上已分组标记 assignedCount++; // 记录已分配人数 groups[i] = group; // 将该分组重新赋值给原数组 break; // 遍历下一个成员 } } });
在上述代码中,我们使用了一个名为assigned的属性作为已分组标记。每位成员在初始化时都未被分组,因此默认为undefined。当某位成员被分配到某个组内后,我们就会将其assigned属性设置为true,以避免重复分组。
上手练习
接下来让我们来进行一个简单的实现过程和实验,使大家更加深入理解如何实现一个前端抽签小程序。
HTML结构
首先,我们需要先创建一些基本的HTML结构,来让用户输入团队成员信息,并设定分组数量和按钮控制器:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>分组抽签小程序</title> <script src="main.js"></script> </head> <body> <h1>分组抽签小程序</h1> <form id="form"> <div> <label for="members">团队成员:</label> <textarea id="members" name="members" placeholder="请用英文半角逗号分隔不同的成员"></textarea> </div> <div> <label for="groups">分组数量:</label> <input type="number" id="groups" name="groups" value="2" min="2"> </div> <button type="submit">开始抽签</button> </form> <div id="result"></div> </body> </html>
JS代码
在JavaScript中,我们需要编写3个函数来实现这个小程序:一是获取关键DOM元素(getInputs),二是执行抽签操作并输出结果(drawLots),三是事件监听逻辑(handleSubmit)。代码如下:
// 获取form表单输入值的函数 function getInputs(form) { const members = form.members.value.trim().split(/[,\n]/).map(m => m.trim()).filter(m => m); // 转换成数组格式,并清理空格和空白行 const groups = +form.groups.value; // 输入分组数量 return { members, groups }; } // 主要操作函数 function drawLots(members, groups) { const baseNum = Math.ceil(members.length / groups); // 计算每组包含多少成员 const shuffledMembers = shuffle(members); // 将成员数组随机排序 let assignedCount = 0; // 计数器,记录已分配的人数 let result = ''; // 定义一个空字符串,用来存放抽签结果 let groupsRes = []; // 定义一个空数组,用来存放每个分组的成员 // 遍历随机排序后的成员列表,进行分组 shuffledMembers.forEach(member => { if (member.assigned) return; // 如果该成员已被分配,则跳过 for (let i = 0; i < groups; i++) { const group = groupsRes[i] || []; // 如果当前分组未定义,则将其初始值设为空数组 if (group.length < baseNum && !group.includes(member)) { // 如果该分组未满员,并且该成员没有被分配到其他组内 group.push(member); // 将该成员加入当前分组 member.assigned = true; // 给该成员打上已分组标记 assignedCount++; // 记录已分配人数 groupsRes[i] = group; // 将该分组重新赋值给原数组 break; // 遍历下一个成员 } } }); // 输出结果 groupsRes.forEach((group, index) => { result += `<h3>第${index+1}组:</h3><ul>`; group.forEach(member => result += `<li>${member}</li>`); result += `</ul>`; }); document.getElementById('result').innerHTML = result; // 修改DOM节点内容,将抽签结果展示给用户 } // 监听表单提交事件 function handleSubmit(event) { event.preventDefault(); const form = event.currentTarget; const { members, groups } = getInputs(form); if (members.length === 0) { alert('请输入团队成员!'); return; } drawLots(members, groups); } document.getElementById('form').addEventListener('submit', handleSubmit); // 挂载监听函数
代码中包括了浅层的代码实现方法,只要牢记三个阶段内容,便可轻松完成这个小程序。
以上就是基于JavaScript开发一个有趣的分组抽签小程序的详细内容,更多关于JavaScript分组抽签程序的资料请关注脚本之家其它相关文章!