果果编程课】007 超级遍历魔法 —— for家族大集合!

(45分钟魔法课 · 适合6-12岁小朋友)

课程目标(今天学会这些大魔法)

  • 认识“for家族”:Racket里最强大、最好玩的遍历魔法!
  • for/list + #:when 完美解决第6课的遗留问题:只挑出「翻倍后加税 >100元」的超级贵糖果!
  • 学会 forfor/listfor/sumfor/firstfor/or 等小精灵。
  • 还能用 in-rangein-naturals 做计数、打印、求和。
  • 把果果糖果店计算器升级成超级智能版

核心口诀
filter 只能筛一次,for 家族能又筛又数又挑又算,一口气搞定所有事!”

第一部分:复习第6课(5分钟)

上节课我们用五大超级魔法做了什么?

1
2
3
4
5
6
7
8
9
(define add-tax (lambda (p) (+ p (* p 0.1))))
(define double (lambda (p) (* p 2)))
(define to-yuan (lambda (p) (string-append (number->string p) "元")))

(define prices (list 10 50 100 30 55 120))

;; 第6课做法(用filter + compose)
(filter (lambda (p) (> (add-tax (double p)) 100))
prices)

遗留问题:我们只拿到了数字,还想要“110元”“220元”这种带文字的漂亮列表,而且想直接在遍历时就过滤!

今天我们用for家族一口气解决!

第二部分:认识“流”(stream)—— 懒惰的魔法数字链(8分钟)

先来两个新朋友:

1
2
(in-range 10)          ; 魔法流:0 1 2 3 4 5 6 7 8 9
(in-naturals) ; 无限魔法流:0 1 2 3 ... 永远不会结束!

比喻:普通list是“一次性把所有糖果倒出来”,stream是“客人要一个才给一个”,超级省力气!

小测试:

1
2
(stream-first (in-range 5))   ; → 0
(stream-ref (in-range 10) 7) ; → 7

第三部分:for家族登场!(20分钟)

1. 最简单 for(像display一样打印)

1
2
3
4
5
6
7
(for ([p prices])
(display (to-yuan p))
(newline))
;; 输出:
;; 10元
;; 50元
;; ...

2. for/list —— 收集成新列表(最常用!)

1
2
3
(for/list ([p prices])
(to-yuan (add-tax (double p))))
;; → '("22元" "110元" "220元" "66元" "121元" "264元")

3. 加过滤魔法 #:when —— 解决遗留问题!

1
2
3
4
5
6
7
(define (super-price lst)
(for/list ([p lst]
#:when (> (add-tax (double p)) 100)) ; 只留下 >100元
(to-yuan (add-tax (double p)))))

(super-price prices)
;; → '("110元" "220元" "121元" "264元")

哇! 第6课的遗留问题一秒解决!🎉

4. for/sum —— 自动求和(买糖果总价神器)

1
2
3
(for/sum ([p prices])
(add-tax (double p)))
;; → 803.0 (所有糖果翻倍加税后的总价)

5. for/first & for/last —— 挑第一个/最后一个符合条件的

1
2
3
4
5
6
7
(for/first ([p prices] #:when (> (add-tax (double p)) 100))
(to-yuan (add-tax (double p))))
;; → "110元" (第一个超级贵糖果)

(for/last ([p prices] #:when (> p 50))
p)
;; → 120 (最后一个>50的原始价格)

6. for/or —— 只要有一个满足就返回 #t

1
(for/or ([p prices]) (> p 100))   ; 有没有超过100元的? → #t

7. 带计数的魔法(in-naturals)

1
2
(for ([p prices] [i (in-naturals)])
(printf "第~a个糖果:~a\n" i (to-yuan p)))

第四部分:实战升级糖果店计算器(10分钟)

把第6课的超级计算器全部换成 for 写法,更简洁!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(define (magic-shop prices)
(printf "=== 果果魔法糖果店 ===\n")
(for ([p prices] [i (in-naturals)])
(printf "第~a个:原价~a → 会员价~a → 实付~a\n"
i
(to-yuan p)
(to-yuan (double p))
(to-yuan (add-tax (double p)))))

(printf "\n超级贵糖果(>100元):~a\n"
(super-price prices))

(printf "今日总收入:~a\n"
(to-yuan (for/sum ([p prices]) (add-tax (double p))))))

(magic-shop (list 10 50 100 30 55 120))

第五部分:小练习(回家作业)

  1. for/list + #:when 做出「只显示打5折后仍然 >60元的糖果」
  2. for/sum 计算1到100所有偶数的平方和(提示:in-range 1 101 2
  3. 挑战:用 for*(嵌套版)打印九九乘法表(选做)
果果编程第7课

下节课预告

第8课:递归魔法 —— 像俄罗斯套娃一样,自己调用自己,无限强大!
(会用递归做出“汉诺塔搬糖果”“无限糖果树”)


老师寄语
今天学会了 for 家族,果果糖果店从“手动挑糖果”变成了“魔法自动流水线”!
把今天的代码复制到 DrRacket 里跑一跑,截图发给爸爸妈妈看~

下课!下节见!🍭✨