如何将函数应用于Clojure中的范围?
我是Clojure的新手,我尝试使用clojuredocs.org上的示例数据如何将函数应用于Clojure中的范围?,clojure,Clojure,我是Clojure的新手,我尝试使用clojuredocs.org上的示例数据 ;; Data (def scenes [{:subject "Frankie" :action "say" :object "relax"} {:subject "Lucy" :action "loves" :object "Clojure"} {:subject "Rich"
;; Data
(def scenes [{:subject "Frankie"
:action "say"
:object "relax"}
{:subject "Lucy"
:action "loves"
:object "Clojure"}
{:subject "Rich"
:action "tries"
:object "a new conditioner"}])
(defn play [scenes n]
"Play a scene"
(->>
scenes
(#(get % n))
((juxt :subject :action :object))
(interpose " ")
(apply str)))
play
功能工作正常:
my-stuff.core> (play scenes 0)
"Frankie say relax"
my-stuff.core> (play scenes 1)
"Lucy loves Clojure"
my-stuff.core> (play scenes 2)
"Rich tries a new conditioner"
此全屏播放功能不起作用:
(defn play-all [scenes]
"Play all the scenes"
(let [x (count scenes)]
(for [n (range x)]
(map play scenes n ))))
如何更正此播放所有功能,即如何将播放功能应用于数据范围?您不需要同时使用和地图
对于
,仅使用:
user=> (defn play-all [scenes]
#_=> "Play all the scenes"
#_=> (let [x (count scenes)]
#_=> (for [n (range x)]
#_=> (play scenes n ))))
#'user/play-all
user=> (play-all scenes)
("Frankie say relax" "Lucy loves Clojure" "Rich tries a new conditioner")
(defn play-all-for [scenes]
"Play all the scenes with for"
(for [scene scenes]
(play-one scene)))
仅使用地图
:
user=> (defn play-all [scenes]
#_=> "Play all the scenes"
#_=> (let [x (count scenes)]
#_=> (map #(play scenes %1) (range x))))
#'user/play-all
user=> (play-all scenes)
("Frankie say relax" "Lucy loves Clojure" "Rich tries a new conditioner")
(我更喜欢后者。)
编辑:如果您喜欢->
,这就更好了:
user=> (defn play-all [scenes]
#_=> "Play all the scenes"
#_=> (->> scenes
#_=> (count)
#_=> (range)
#_=> (map #(play scenes %))))
#'user/play-all
user=> (play-all scenes)
("Frankie say relax" "Lucy loves Clojure" "Rich tries a new conditioner")
map
迭代一个集合(或多个集合)以生成序列。
用于
从。
在您的情况下,您可以使用其中一个或另一个
就分解而言,它将使sens实际上拥有一个播放一个场景的功能:
然后播放第n个可以使用先例定义:
(defn play-nth [scenes n]
"Play the n(th) scene"
(->
scenes
(#(get % n))
play-one))
你有几种方法来播放所有的场景:
(defn play-all-map1 [scenes]
"Play all the scenes"
(map (partial play-nth scenes) (range (count scenes))))
但是您确实可以简化,因为您不需要范围
,因为场景
可以被视为一个序列(假设您对索引不感兴趣):
对于
,使用:
user=> (defn play-all [scenes]
#_=> "Play all the scenes"
#_=> (let [x (count scenes)]
#_=> (for [n (range x)]
#_=> (play scenes n ))))
#'user/play-all
user=> (play-all scenes)
("Frankie say relax" "Lucy loves Clojure" "Rich tries a new conditioner")
(defn play-all-for [scenes]
"Play all the scenes with for"
(for [scene scenes]
(play-one scene)))
在我们对其执行任何操作之前,您的play
函数应处理单个场景:
(defn play [scene]
"Play a scene"
(->> scene
((juxt :subject :action :object))
(interpose " ")
(apply str)))
你这样使用它:
(play (scenes 0))
;"Frankie say relax"
。。。这并不比以前容易或难。但是
- 它适用于任何场景和场景
- 场景不必保存在向量中李>
它还使播放所有的变得更简单:
(defn play-all [ss]
(map play ss))
(play-all scenes)
;("Frankie say relax" "Lucy loves Clojure" "Rich tries a new conditioner")
我曾试图在播放中用VAL
替换((juxt:subject:action:object))
,但我们不能依赖地图条目的顺序 您可以定义(def play nth(comp play nth))
。几乎所有这些都在我撰写本文时发布。感谢您的详细解释。