如何理解这个简单的clojure代码?我有点理解它试图做什么,但有人可以详细解释语法,以便我可以自信地使用它吗?
(map (fn [x] (.toUpperCase x)) (.split "Dasher Dancer Prancer" " "))
</p>
如何理解这个简单的clojure代码?我有点理解它试图做什么,但有人可以详细解释语法,以便我可以自信地使用它吗?
(map (fn [x] (.toUpperCase x)) (.split "Dasher Dancer Prancer" " "))
</p>
来自 Clojure REPL:
(doc map)
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) 返回一个惰性序列,该序列由将 f 应用于第一个集合的结果组成每个 coll 的项目,然后将 f 应用于每个 coll 中的第二个项目的集合,直到用完任何一个 coll。其他 colls 中的任何剩余项目都将被忽略。函数 f 应该接受 number-of-colls 参数。
(.split "Dasher Dancer Prancer" " ")正在生成一个字符串序列,每个标记化的字符串将被传递给(fn [x] (.toUpperCase x))
但是, (fn [x] (.toUpperCase x)) 是太多不必要的输入。你可以做:
(map #(.toUpperCase %) (.split "Dasher Dancer Prancer" " "))
或者:
(map (memfn toUpperCase) (.split "Dasher Dancer Prancer" " "))
这是定义一个 lambda(一个匿名函数,它调用toUpperCase
它的单个参数),并将它(使用 map)应用到String.split()
.
map
接受一个函数和一系列将该函数应用到的事物,并返回将该函数应用于输入序列的一系列结果。
以下将操作分解为更小的部分:
(defn upper-case-fn [^String x]
"this makes the same function, but not anonymous, and provides a type hint
(making it more efficient by avoiding the need for reflection)."
(.toUpperCase x))
;; you could also write the above like so:
(def upper-case-fn (fn [x] (.toUpperCase x)))
(def input-seq
"this assigns your input seq to a var; in the real world, with dynamic data,
you wouldn't do this"
(.split "Dasher Dancer Prancer" " "))
(def output-seq
"this is precisely the same as your sample, except that it's using a named
function rather than an anonymous one, and assigns the output to a var"
(map upper-case-fn input-seq))
;; if you enter this at a repl, you're looking at the contents of this var
output-seq