我现在正在学习 Clojure,我来自命令式编程,所以我在理解该代码的执行流程时遇到了问题:
(defn chop-chop [coll]
(let [x (partition-by identity coll)]
(map list (map (comp str first) x)
(map count x))))
=> (chop-chop "aaaabbbcca")
=> (("a" 4) ("b" 3) ("c" 2) ("a" 1))
Run Code Online (Sandbox Code Playgroud)
我明白我们:
在此处创建带有参数 coll 的函数chop-chop
然后我们为 coll 应用函数 partition-by,但我不确定身份是什么
接下来我们将之前操作的结果绑定到 x
但我无法理解下一行代码:
(map list (map (comp str first) x)
(map count x))))
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释该程序的逐步执行流程吗?非常感谢!
这个例子:
关于你的四颗子弹:
defn宏定义的单元函数identity返回参数;; Possible values: 1, :a, #(+ 1 2), {:a [1 2]}
(identity 1) ;;=> 1
(identity :a) ;;=> :a
(identity #(+ 1 2)) ;;=> #function[boop.core/eval7764/fn--7765]
(identity {:a [1 2]}) ;;=> {:a [1 2]}
(partition-by identity "aaaabbbcca") ;;=> (\a \a \a \a) (\b \b \b) (\c \c) (\a))
Run Code Online (Sandbox Code Playgroud)
以防万一您不了解 partition-by,它会在每次函数值更改时创建一个新组。#(< 3 %)将false用于1,2。由于结果相同,因此将它们分组在一起。3 4 5将具有相同的结果,因此它们将组合在一起。
;; f
;; =
;; number?
;; coll
;; [1 2 3 4 5]
;; [:a :b '(:Yo) 3]
;; f1 coll1
(partition-by #(= 3 %) [1 2 3 4 5]) ;;=> ((1 2) (3) (4 5))
;; f1 coll2
(partition-by #(= 3 %) [:a :b '(:Yo) 3]) ;;=> ((:a :b (:Yo)) (3))
;; f2 coll1
(partition-by number? [1 2 3 4 5]) ;;=> ((1 2 3 4 5))
;; f2 coll2
(partition-by number? [:a :b '(:Yo) 3]) ;;=> ((:a :b (:Yo)) (3))
Run Code Online (Sandbox Code Playgroud)
x. 这个例子映射了两个 map,所以如果他们将两个 map 绑定到 variables 会更清楚:(defn chop-chop [coll]
(let [x (partition-by identity coll)
;; Could bind the two maps here
first-letter-map (map (comp str first) x)
repeating-letter-count (map count x)]
;; a map of maps
(map list first-letter-map repeating-letter-count)))
(chop-chop "aaaabbbcca") ;;=> (("a" 4) ("b" 3) ("c" 2) ("a" 1))
Run Code Online (Sandbox Code Playgroud)
地图可以映射一个或多个集合。
这是每张地图的一个集合:
;; maps
;; (map (comp str first) x)
;; (map count x)
;; coll
;; [["woo" "yes"] ["hello" "world"]]
;; ((\a \a \a \a) (\b \b \b) (\c \c) (\a)), the result of (partition-by identity "aaaabbbcca")
;; m1 c1
(map (comp str first) [["woo" "yes"] ["hello" "world"]]) ;;=> ("woo" "hello")
;; m1 c2
(map (comp str first) '((\a \a \a \a) (\b \b \b) (\c \c) (\a))) ;;=> ("a" "b" "c" "a")
;; m2 c1
(map count [["woo" "yes"] ["hello" "world"]]) ;;=> (2 2)
;; m2 c2
(map count '((\a \a \a \a) (\b \b \b) (\c \c) (\a))) ;;=> (4 3 2 1)
Run Code Online (Sandbox Code Playgroud)
这是每张地图的两个集合:
;; function
;; #(str (first %1) (first %2))
;; #(list (count %1) (count %2))
;; same colls, but passed in at the same time
;; [["woo" "yes"] ["hello" "world"]]
;; ((\a \a \a \a) (\b \b \b) (\c \c) (\a))
(def c1 [["woo" "yes"] ["hello" "world"]])
(def c2 '((\a \a \a \a) (\b \b \b) (\c \c) (\a)))
(map #(str (first %1) (first %2)) c1 c2) ;;=> ("wooa" "hellob")
(map #(list (count %1) (count %2)) c2 c1) ;;=> ((4 2) (3 2))
Run Code Online (Sandbox Code Playgroud)
你还应该明白comp:
;; comp vs. personall const
;; (comp str first)
;; #(str (first %))
;; seq
;; [\a "Wow"]
;; [132 :a]
;; c1 s1
((comp str first) [\a "Wow"]) ;;=> "a"
;; c2 s1
(#(str (first %)) [\a "Wow"]) ;;=> "a"
;; c1 s2
((comp str first) [132 :a]) ;;=> "132"
;; c2 s2
(#(str (first %)) [132 :a]) ;;=> "132"
Run Code Online (Sandbox Code Playgroud)
欢迎来到 Clojure 社区!