对于序列理解,'map'和'for'

1 clojure

两天前我开始学习Clojure,没有任何函数式编程经验.今天,在通过" 编程Clojure "一书阅读阅读时,我遇到了一个问题.

这是关于转换序列.有一个例子:

(map #(format ?"<%s>%s</%s>"? %1 %2 %1)
    [?"h1"? ?"h2"? ?"h3"? ?"h1"?] [?"the"? ?"quick"? ?"brown"? ?"fox"?])
Run Code Online (Sandbox Code Playgroud)

产生结果:

-> (?"<h1>the</h1>"? ?"<h2>quick</h2>"? ?"<h3>brown</h3>"? "<h1>fox</h1>?"?)
Run Code Online (Sandbox Code Playgroud)

这对我来说并不难.实际上,当这本书告诉我for一般可以用来产生序列理解然后给我看一个例子时就会出现问题.这个例子有点简单,我完全可以理解它.

当我尝试重写我第一次提到的例子时for,问题就出现了.

我可以得到:

("<h1>the</h1>"
"<h1>quick</h1>"
"<h1>brown</h1>"
"<h1>fox</h1>"
"<h2>the</h2>"
"<h2>quick</h2>"
"<h2>brown</h2>"
"<h2>fox</h2>"
"<h3>the</h3>"
"<h3>quick</h3>"
"<h3>brown</h3>"
"<h3>fox</h3>"
"<h1>the</h1>"
"<h1>quick</h1>"
"<h1>brown</h1>"
"<h1>fox</h1>")
Run Code Online (Sandbox Code Playgroud)

使用重写的代码:

(for [label ["h1" "h2" "h3" "h1"] word ["the" "quick" "brown" "fox"]]
    (format "<%s>%s</%s>" label word label))
Run Code Online (Sandbox Code Playgroud)

我被告知通常使用:when条款可能会有所帮助,但我无法想到它.

我怎么能重写代码,for以便答案与map版本完全相同?

Tay*_*ood 5

正如你所见,当你有多个绑定时,for它就像其他命令式语言中的"嵌套for循环"一样,好像你有一个外部for循环label和一个内部for循环word.因此,您可以获得两个集合的价值的每个组合.

 for (label in labels)
   for (word in words)
      print(word + " " + label);
Run Code Online (Sandbox Code Playgroud)

我能想象用这个问题来解决这个问题的最简单的方法无论如何for都需要map,所以我会使用你原来的简单map解决方案.

(def pairs ;; a vector of tuples/pairs of labels/words
  (map vector ["h1" "h2" "h3" "h1"] ["the" "quick" "brown" "fox"]))
;; (["h1" "the"] ["h2" "quick"] ["h3" "brown"] ["h1" "fox"])
(for [[label word] pairs] ;; enumerate each pair
  (format "<%s>%s</%s>" label word label))
=> ("<h1>the</h1>" "<h2>quick</h2>" "<h3>brown</h3>" "<h1>fox</h1>")
Run Code Online (Sandbox Code Playgroud)

将多个集合args传递map给映射函数时,每个映射步骤都会从每个集合中接收一个项目.如果您只有一个输入集合,则等效项for看起来非常相似.

  • 我唯一一次使用`for`是因为我需要它来生成序列组合,或者使用`:while` /`:when`.`map`绝对是正确的工具. (2认同)