首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Clojure代码的执行流程

理解Clojure代码的执行流程
EN

Stack Overflow用户
提问于 2021-02-07 08:15:22
回答 2查看 156关注 0票数 0

我现在正在学习Clojure,我来自命令式编程,所以我很难理解代码的执行流程:

代码语言:javascript
复制
(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))

据我了解,我们:

  1. 在这里创建带有参数coll

的函数chop

然后,我们将函数分区应用于coll,但我不确定什么是

  1. 下一步我们将以前操作的结果绑定到x

  1. ,但我不能理解下一行代码:

代码语言:javascript
复制
(map list (map (comp str first) x)
    (map count x))))

有人能解释一下那个程序的一步一步的执行流程吗?非常感谢!

EN

回答 2

Stack Overflow用户

发布于 2021-02-07 12:00:53

jist

这个例子:

  1. 获取一个集合(在本例中为字符串),
  2. 获取组上的重复字母
  3. 映射组,以获得组上具有代表性的字母
  4. 映射,以获得组内每个组
  5. 映射的计数,以获得键值元组、字母及其重复次数(在此情况下,不是所有时间)。H 210G 211G 211

The jist+

在你的四颗子弹上

  1. Yup,它是一个用defn
  2. Yup定义的单一的函数,identity返回参数

代码语言:javascript
复制
;; 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))

如果您不理解分区-by,每次函数的值发生变化时,它都会创建一个新的组。#(< 3 %)将成为12false。因为结果是相同的,所以它们被聚在一起。3 4 5将具有相同的结果,因此它们将被分组。

代码语言:javascript
复制
;; 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))

  1. 是的,您可以将前面的操作绑定到x。这个示例映射两个映射(),因此如果将两个映射绑定到变量

,则会更清楚

代码语言:javascript
复制
(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))

关于最后一段代码的

地图可以在一个或多个集合上映射。

以下是每幅地图的一个集合:

代码语言:javascript
复制
;; 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)

以下是每幅地图的两个集合:

代码语言:javascript
复制
;; 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))

你也应该了解comp

代码语言:javascript
复制
;; 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"

欢迎来到Clojure社区!

票数 5
EN

Stack Overflow用户

发布于 2021-02-07 09:15:26

partition-bycol中的每个值应用函数identity,每次返回新值时它都会拆分col。例如:

代码语言:javascript
复制
user=> (partition-by #(= 3 %) [1 2 3 4 5])
((1 2) (3) (4 5))

它使用函数(= 3 %)进行分区,因此它将(1 2)分为3部分,(3)为false,(4 5)为false。您正在使用identity作为函数,aa函数返回其参数。(partition-by identity "aaaabbbcca")返回((\a \a \a \a) (\b \b \b) (\c \c) (\a))

接下来您要执行(map count x),所以您正在计算x的每个列表,返回:(4 3 2 1)(map (comp str first) x)返回一个字符串,其中包含x("a" "b" "c" "a")中每个列表的第一个字符。

最后,你要做的是:

代码语言:javascript
复制
 (map list '("a" "b" "c" "a") 
                '(4 3 2 1))))

这将创建一个组合了两个列表的列表:例如,使用每个列表的第一个元素:(list "a" 4)-> ("a" 4)使用以下四个元素执行此操作:

代码语言:javascript
复制
 (("a" 4) ("b" 3) ("c" 2) ("a" 1))
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66085819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档