JavaScript 数组:筛选任务并避免原地排序污染数据
用 filter 与 reduce 统计完成任务,再通过数组副本排序,观察 sort 的修改行为与浅拷贝的边界。
本节目标
用 filter 与 reduce 统计完成任务,再通过数组副本排序,观察 sort 的修改行为与浅拷贝的边界。
环境与运行方法
准备 Node.js 22 或更新版本。把完整代码保存为 lesson.mjs,执行 node lesson.mjs。本组示例使用命令行标准输出,不依赖浏览器 DOM,也不安装第三方包。
核心思路
filter 生成筛选结果,reduce 把多项累计为一个值。sort 会修改被调用的数组,因此展示层需要不同顺序时,先复制外层数组,避免改变其他组件依赖的原始顺序。
完整示例
const tasks = [
{title: "review", minutes: 20, done: true},
{title: "practice", minutes: 40, done: false},
{title: "read", minutes: 10, done: true}
];
const completed = tasks.filter(task => task.done);
const total = completed.reduce((sum, task) => sum + task.minutes, 0);
const ordered = [...tasks].sort((a, b) => b.minutes - a.minutes);
console.log("completed=" + completed.length + " total=" + total);
console.log("first=" + ordered[0].title);
console.log("original=" + tasks[0].title);预期输出
completed=2 total=30
first=practice
original=review逐步理解
reduce 的初始值为 0,所以空完成集合也能求和,不会因为没有首个元素而报错。排序比较器返回数值差,实现分钟数降序;省略比较器会按默认字符串规则排序,不能表示数字大小。
展开运算符只复制外层数组,任务对象仍共享。改变 ordered[0].done 仍会影响原任务对象。若要编辑某个任务,应根据业务需要复制对象或构造新对象,而不是把外层复制误认为深拷贝。
常见问题与边界
- sort 返回的仍是被修改的数组。
- reduce 没有初始值时,空数组会失败。
- 过滤并不自动验证字段类型,外部 JSON 要先校验。
动手练习
把全部 done 改成 false,再验证总和。
参考答案
完成数量为 0,总和为 0,排序仍按原任务分钟数排列。过滤条件和排序条件独立,改变完成状态不会自动改变分钟数。
文章回复
0 条公开回复