SICP 中 `flatmap` 的意义是什么?
What is the significance of `flatmap` in SICP?
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
(define (flatmap proc seq)
(accumulate append nil (map proc seq)))
以上是 Scheme 中 SICP 的代码片段。为什么需要 flatmap
程序? flatmap
和 map
有什么区别?
(map proc seq)
将对序列 seq
应用 proc
,为每个元素返回一个值。每个这样的值都可能是另一个序列。
(accumulate append nil seq)
将使用 append
将 seq
中元素的所有副本连接到一个新列表中。
因此,flatmap
将对 seq
的所有元素应用 proc
,并生成包含所有结果的新 flattened 列表。从概念上讲,这也是 map
和 flatmap
在其他语言(Java、Scala 等)中的区别,因为 map
为每个元素生成一个值,而 flatmap
可能会产生多个或 none (感谢 Chris)。
例如,在 Clojure 中:
(map #(clojure.string/split % #"\s+") ["two birds" "with one stone"])
;; => (["two" "birds"] ["with" "one" "stone"])
(mapcat #(clojure.string/split % #"\s+") ["two birds" "with one stone"])
;; => ("two" "birds" "with" "one" "stone")
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
(define (flatmap proc seq)
(accumulate append nil (map proc seq)))
以上是 Scheme 中 SICP 的代码片段。为什么需要 flatmap
程序? flatmap
和 map
有什么区别?
(map proc seq)
将对序列 seq
应用 proc
,为每个元素返回一个值。每个这样的值都可能是另一个序列。
(accumulate append nil seq)
将使用 append
将 seq
中元素的所有副本连接到一个新列表中。
因此,flatmap
将对 seq
的所有元素应用 proc
,并生成包含所有结果的新 flattened 列表。从概念上讲,这也是 map
和 flatmap
在其他语言(Java、Scala 等)中的区别,因为 map
为每个元素生成一个值,而 flatmap
可能会产生多个或 none (感谢 Chris)。
例如,在 Clojure 中:
(map #(clojure.string/split % #"\s+") ["two birds" "with one stone"])
;; => (["two" "birds"] ["with" "one" "stone"])
(mapcat #(clojure.string/split % #"\s+") ["two birds" "with one stone"])
;; => ("two" "birds" "with" "one" "stone")