← FC Coder · HomePhase 01 · Lesson 15 · 60 min
Lesson15
Phase One · First App · Final · Matchday 15 · 🏆 Demo Day 3
筛选 + 排序
Demo Day 3
Today's 3 Jobs · 今天这三件事
- 01.filter 按国籍 / 俱乐部筛 · 球探的活.filter(p => p.club === '曼城')
- 02.sort 按评分排 · 必须 [...arr].sort(a, b) => b.rating - a.rating
- 03🏆 演给妈妈和家人 · Demo Day 3讲 if / .filter / .sort 3 件事
Phase 1 终章。学 .filter(球探活) + .sort(教练活) —— 把 50 人按俱乐部 / 国籍筛 · 按评分排。然后演给妈妈 —— Phase 1 Demo Day 3。讲得清「.filter 和 .sort 是函数」就过。
Essence · 一份名单的三种动作
筛 · 排 · 变形
.filter 筛(留 / 扔)· .sort 排(换顺序)· .map 变形(每个换一个样子,上节课的事)。
players.filter(p => p.club === '曼城')
↓
[...cityPlayers].sort((a, b) => b.rating - a.rating)
↓
.map(player => <article>...</article>)
↓
[...cityPlayers].sort((a, b) => b.rating - a.rating)
↓
.map(player => <article>...</article>)
.filter
留符合 / 扔其他
.sort
按字段重排
.map
每个变形为新东西
球探用 .filter · 教练用 .sort · 队医用 .map(每人开体检单)。三个动作覆盖名单管理。
Essence · spread 的为什么
.sort 改原数组 · 必须先 [...arr] 复制
Phase 0 第 5 课 Math.max(...ratings) 见过的 ... 同一个姿势。
[...players].sort((a, b) => b.rating - a.rating) 高到低
[...players].sort((a, b) => a.rating - b.rating) 低到高
[...players].sort((a, b) => a.rating - b.rating) 低到高
坑
players.sort(...) · players 被改了!
解
[...players].sort(...) · 原数组不动
为什么
JS 历史 + 性能 · 抄就好
不解释 .sort 为什么 in-place(那是 JS 历史决定 · 改不了)。今天只抄「先 spread 再 sort」。
Roster · 今天 3 个新工具
.filter · .sort · spread
抄着用 · 改条件看变化 · 综合到 Demo Day 演示。
- 01players.filter(p => p.club === '曼城')球探的活 —— 留符合条件 · 扔其他。返回新数组(原不动)。=== 完全相等 · 严格匹配。
- 02[...players].sort((a, b) => b.rating - a.rating)教练的活 —— 按某字段重排。必须 [...arr] 预先复制。b - a 高到低 / a - b 低到高。比较函数今天抄着用。
- 03[...players]摊开复制 —— 防 .sort 改原数组。Phase 0 第 5 课 Math.max(...) 见过同一个 ...。不复制直接 sort · 会修改 players · 其他地方出错。
Half 2 · 在屏幕上
筛 · 排 · 综合 · 然后给妈妈演
做完一步就点 ✓。Step 10-12 是 Demo Day 3 仪式。
01球探活 · .filter 筛
01Min
Cursor + pnpm dev
回 07-my-first-card/sandbox。看 22 人卡。
02Min
const filtered = players.filter(p => p.nationality === '挪威');
替换 .map 用 filtered。保存 · 只剩挪威人(1 张 · 哈兰德)。
03Min
改 '挪威' 成 '西班牙'
保存 · 看西班牙球员 · 罗德里 / 佩德里 / 亚马尔(看你写的 22 人)。
04Min
按俱乐部 · '曼城'
.filter(p => p.club === '曼城')。保存 · 11 张曼城卡。
02教练活 · [...].sort 排
05Min
🌟 [...cityPlayers].sort((a, b) => b.rating - a.rating)
把 .map 链:{[...cityPlayers].sort((a, b) => b.rating - a.rating).map(...)}。保存 · 11 张按评分高到低。罗德里 90 / 德布劳内 88 / ...
06Min
改 (a, b) => a.rating - b.rating · 低到高
交换 a 和 b · 保存 · 最低分在前。这是排序方向的开关。改回 b - a。
03综合 · 切换变量 · 整页换
07Min
顶部加 const selectedClub = '曼城';
整理变量在 sandbox 顶部 · const selectedClub = '曼城'; const filtered = players.filter(p => p.club === selectedClub); const sorted = [...filtered].sort((a, b) => b.rating - a.rating);
08Min
加 'ALL' 模式 · 三元 ?:
const filtered = selectedClub === 'ALL' ? players : players.filter(p => p.club === selectedClub); 抄着用 · 三元 Phase 2 末讲。改 selectedClub = 'ALL' 看全 22 张。
04🏆 Demo Day 3 · 演给妈妈
09Min
顶部加 <h1>{selectedClub} 阵容 · 按评分排</h1>
演示用 · 让妈妈一眼看到当前显示的是什么。
10Min
演练 3 次 · 给爸爸 2 次 + 妈妈 1 次
讲 3 件事:(1) 50 人是你写的 JSON · (2) if 决定金边 · (3) .filter / .sort 是函数 · 写一次用很多次。改 selectedClub 切换队。
11Min
🏆 Demo Day 3 · 真演给家人
5 分钟演示 + 5 分钟问答 + 大合照。妈妈和长辈在场。R3 命中:讲得清。R4 命中:爸爸临场改 filter 条件你能改对。
12Min
📸 Phase 1 毕业照
Mac Shift + Cmd + 4 · 存 2026-XX-XX-DemoDay3.png · Phase 1 最后一张战利品。把 9 张战利品放一起 · 完整赛季。
Demo Day 3 · 给妈妈讲的 4 题
先给爸爸讲一遍 · 再正式演
讲得清 .filter / .sort 是函数 · R3 命中。
01这 50 人是怎么来的?(妈妈一定问)Hint ↓
我自己写的 JSON 文件 · 不是 AI 生成 · 不是从 ea.com 复制。50 人是「我的」名单。
02.filter 干什么?用「球探」的比喻。Hint ↓
筛选 · 留下符合条件 · 扔掉其他。返回新数组,原数组不动。
03.sort 怎么用?为什么要 [...players].sort 不是 players.sort?Hint ↓
.sort 改原数组。我们不能改 · 预先用 ...spread 复制一份再排。
04.filter(p => p.club === '曼城') 这 p => ... · 是函数吗?Hint ↓
是。箭头函数版的函数。和 function byRating(min) 同一回事 · 写法不同。
Player Rating · 本课温度计
给 Phase 1 整体打个分
15 节课 · 你看到自己变了多少。说真话。
今天难度Difficulty
0
今天开心Fun
0
Final Whistle · 终场哨
🏆 Phase 1 完赛 —— 从打开 Cursor 到自己的 50 人球员库 + 演示。
还有 12 步没打勾。Demo Day 3 可以推迟 · 仪式比准时重要。其他步骤本周补完。