惰性 map 与 filter
串联惰性转换而不创建中间数组。
惰性 map 与 filter 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
中间数组
立即执行的串联过程会在每个步骤之间分配一个新数组。对大型数组执行 filter().map() 会构建两个完整数组,即使您可能只需要其中几个元素。
立即执行的分配
这里会创建两个中间数组:
let nums = Array(1...6)
let result = nums
.filter { $0 % 2 == 0 } // builds [2, 4, 6]
.map { $0 * 10 } // builds [20, 40, 60]
print(result) // [20, 40, 60]使用惰性处理融合步骤
惰性串联会融合这些操作:每个元素都会依次经过所有步骤,然后才开始处理下一个元素,因此完全不会分配中间数组。
惰性串联
逻辑相同,但不会创建中间数组:
let nums = Array(1...6)
let result = nums.lazy
.filter { $0 % 2 == 0 }
.map { $0 * 10 }
print(Array(result)) // [20, 40, 60]逐元素流动
跟踪执行过程可以看到交错执行,而不是按阶段执行:
let out = [1, 2, 3].lazy
.filter { n -> Bool in print("filter \(n)"); return n > 1 }
.map { n -> Int in print("map \(n)"); return n }
print(Array(out)) // filter 1, filter 2, map 2, filter 3, map 3 -> [2, 3]提前退出可节省工作量
将惰性串联与 first(where:) 结合,以便在条件满足时立即停止:
let nums = Array(1...1_000_000)
let hit = nums.lazy.map { $0 + 1 }.first { $0 > 5 }
print(hit!) // 6 -- only a handful of elements processed使用惰性处理与 prefix
只获取开销较大的转换结果中的前几个:
let squares = (1...).lazy.map { $0 * $0 }
print(Array(squares.prefix(5))) // [1, 4, 9, 16, 25]统计跳过的工作
计数器可以证明实际运行的元素有多么少:
var transforms = 0
let result = Array(1...100).lazy
.map { (n: Int) -> Int in transforms += 1; return n * 2 }
.prefix(3)
_ = Array(result)
print(transforms) // 3, not 100惰性紧凑映射
紧凑映射也有惰性形式:
let raw = ["1", "x", "3", "y", "5"]
let first = raw.lazy.compactMap { Int($0) }.first
print(first!) // 1混合多个步骤
较长的融合管线在具体化之前都不会分配数组:
let r = Array(1...20).lazy
.filter { $0 % 2 == 0 }
.map { $0 * $0 }
.filter { $0 > 50 }
print(Array(r)) // [64, 100, 144, 196, 256, 324, 400]融合最有帮助的情况
当源数据很大,而您只保留部分结果时,惰性融合非常有优势。如果最终仍然要将全部内容消费到数组中,节省的开销就会减少,此时立即执行的写法可能更清晰。
let big = Array(1...10_000)
let sample = Array(big.lazy.filter { $0 % 1000 == 0 })
print(sample) // [1000, 2000, ... 10000]快速检查
惰性的 filter().map() 串联会避免什么,而立即执行的串联会创建什么?
回顾
您已经学习了惰性串联:
- 立即执行的串联会在每个步骤之间分配一个数组
.lazy会融合各个步骤 — 逐元素处理,不创建中间结果- 它与
first(where:)和prefix搭配时非常适合提前退出 - 最大的优势:源数据很大,但只消费其中一部分
接下来:惰性处理与立即执行的权衡。
常见问题解答
「惰性 map 与 filter」课时是免费的吗?
是的 — 「惰性 map 与 filter」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「惰性 map 与 filter」这节课中我会学到什么?
串联惰性转换而不创建中间数组。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「惰性 map 与 filter」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- lazy 属性
- 惰性 map 与 filter
- 惰性与即时求值的权衡
- 构建自定义惰性序列