
本文介绍如何将学生数组按每组3人进行分组,并在末尾统一添加一行“rest students: x”标识剩余人员;当无剩余时显示“-”,避免重复插入或逻辑错乱。
本文介绍如何将学生数组按每组3人进行分组,并在末尾统一添加一行“rest students: x”标识剩余人员;当无剩余时显示“-”,避免重复插入或逻辑错乱。
在实现学生分组功能时,常见误区是在循环中动态判断并插入“Rest students”字符串,这会导致:
- 当某组不足3人时提前插入,后续仍继续分组,造成冗余项(如示例中出现 [ 'Takesi' ] 和 'Rest students: Takesi' 并存);
- 无法统一控制“Rest”行的位置与格式,尤其在恰好整除时难以输出 'Rest students: -'。
✅ 正确思路是:先完成全部等长分组 → 单独处理最后一组 → 根据其长度决定最终追加内容。
以下是优化后的完整实现:
function sortStudentsByGroups(arr, groupSize = 3) {
// 深拷贝并排序(避免修改原数组)
const sorted = [...arr].sort();
const groups = [];
// 第一步:均匀切分所有完整组
for (let i = 0; i < sorted.length; i += groupSize) {
groups.push(sorted.slice(i, i + groupSize));
}
// 第二步:提取最后一组,判断是否为不完整组
const lastGroup = groups.pop();
if (lastGroup.length === groupSize) {
// 恰好整除:追加占位符 '-'
groups.push(`Rest students: -`);
} else {
// 存在剩余:拼接剩余学生姓名(用逗号分隔)
const restNames = lastGroup.join(', ');
groups.push(`Rest students: ${restNames}`);
}
return groups;
}
// ✅ 测试用例 1:9人 + 1剩余 → 3组 + 1个Rest项
const students1 = [
"Peter", "Andrew", "Ann", "Mark", "Josh",
"Sandra", "Cris", "Bernard", "Takesi", "Sandra"
];
console.log(sortStudentsByGroups(students1));
// 输出:
// [
// [ 'Andrew', 'Ann', 'Bernard' ],
// [ 'Cris', 'Josh', 'Mark' ],
// [ 'Peter', 'Sandra', 'Sandra' ],
// 'Rest students: Takesi'
// ]
// ✅ 测试用例 2:删除1人后共9人 → 恰好整除 → 显示 '-'
const students2 = students1.slice(0, -1); // 移除最后一个 'Sandra'
console.log(sortStudentsByGroups(students2));
// 输出:
// [
// [ 'Andrew', 'Ann', 'Bernard' ],
// [ 'Cris', 'Josh', 'Mark' ],
// [ 'Peter', 'Sandra', 'Takesi' ],
// 'Rest students: -'
// ]? 关键设计说明:
- 使用 groups.pop() 提前取出最后一组,确保“Rest students”只出现一次且位置固定在末尾;
- groupSize 设为可选参数(默认 3),提升函数复用性;
- 排序前用 [...arr] 浅拷贝,防止副作用影响原始数据;
- 剩余学生名使用 join(', ') 格式化,符合题目要求的可读性。
⚠️ 注意事项:
- 若原始数组含重复姓名(如两个 "Sandra"),排序后会相邻显示,属正常行为;如需去重,应在排序前调用 Array.from(new Set(arr));
- 该方案时间复杂度为 O(n log n)(主因排序),空间复杂度 O(n),适用于常规教学场景。
通过分离“分组”与“收尾处理”两个阶段,逻辑清晰、边界明确,轻松覆盖题目中的两种典型情况。

















