我想这样做:
(-> string
(str/split "\s")
(modification-1)
(modification-2)
…
(modification-n
(str/join "\n"))
但不,分割需要[s regex]
并加入[seperator coll]
。
这种疯狂有没有明显的原因(读:这背后的设计决定是什么)?
答案 0 :(得分:8)
从Clojure 1.5开始,您还可以使用其中一个新的线程宏。
clojure.core /原样>
([expr name& forms])
宏
将name绑定到expr,计算词法上下文中的第一个表单 该绑定然后将名称绑定到该结果,为每个结果重复 连续形式,返回最后一个表格的结果。
这是一个非常新的构造,所以不确定如何使用惯用法,但我想这样的事情会这样做:
(as-> "test test test" s
(str/split s #" ")
(modification-1 s)
(modification-2 s)
...
(modification-n s)
(str/join "\n" s))
修改强>
至于为什么辩论的立场不同,我无处可说,但我认为亚瑟的建议是有道理的:
map
,reduce
等)进行操作。这些往往始终将集合作为最后一个参数,这意味着它们与->>
/
时,我们期望分子首先出现。这些功能最适合->
事情是 - 有些功能含糊不清。他们可能会收集一个集合并生成一个值,或者生成一个值并生成一个集合。 string\split
就是一个例子(暂时忽略了一个字符串可以被认为是单个值或集合的额外混淆)。连接/减少操作也会这样做 - 它们会弄乱你的管道!
考虑一下,例如:
(->> (range 1 5)
(map inc)
(reduce +)
;; at this point we have a single value and might want to...
(- 4)
(/ 2))
;; but we're threading in the last position
;; and unless we're very careful, we'll misread this arithmetic
在这些情况下,我认为as->
之类的内容确实非常有用。
我认为一般来说,在对集合进行操作时使用->>
的准则和->
其他方面也是合理的 - 而且只是在这些边缘/模糊的情况下,as->
可以使代码成为小整洁,更清晰一点。
答案 1 :(得分:2)
您可以使用partial函数来修复str / join的分隔符参数。
(-> string
(str/split #"\s")
(modification-1)
(modification-2)
;;
(modification-n)
((partial str/join "\n")))
答案 2 :(得分:2)
我也经常遇到这种(次要的)线程问题。
(-> string
(str/split "\s")
(modification-1)
(modification-2)
…
(modification-n
(#(str/join "\n" %)))
并经常创建一个匿名函数来进行排序匹配。我猜测为什么一些函数用于线程优先->
,一些用于线程最后->>
和一些线程不是设计目标,尽管这只是猜测。
答案 3 :(得分:0)
通过另一个线程宏线程化线程表达式没有任何问题,如下所示:
(-> string
(str/split "\s")
modification-1
modification-2
modification-n
(->> (str/join "\n")))