Dictionary 如何";“过滤器”;在Clojure中正确映射?
我和Clojure在一起玩了一段时间,我陷入了一些我认为对很多人来说都很琐碎的事情中……但不是我。我有下面的一段代码Dictionary 如何";“过滤器”;在Clojure中正确映射?,dictionary,clojure,Dictionary,Clojure,我和Clojure在一起玩了一段时间,我陷入了一些我认为对很多人来说都很琐碎的事情中……但不是我。我有下面的一段代码 ;; Define a Record structure (defrecord Person [first-name last-name age occupation]) (def john (->Person "John" "Frusciante" 50 "Guitarist")) ;; People map
;; Define a Record structure
(defrecord Person [first-name last-name age occupation])
(def john (->Person "John" "Frusciante" 50 "Guitarist"))
;; People map
(def people {"1" john
"2" (->Person "Pablo" "Neruda" 90 "Poet")
"3" (->Person "Stefan" "Zweig" 120 "Author")
}
)
(defn get-120-year-old-guy
[peeps]
(filter #(= (:age %) 120) peeps)
)
(println "who's 120?: " (get-120-year-old-guy people))
此调用返回一个空列表。我知道我检索值的方式有问题,但看不清具体是什么。您可以通过临时更改函数来了解情况:
(defn get-120-year-old-guy
[peeps]
(filter (fn [m] (println (type m) m)) peeps))
印刷品:
(clojure.lang.MapEntry [1 #user.Person{:first-name John, :last-name Frusciante, :age 50, :occupation Guitarist}]
clojure.lang.MapEntry [2 #user.Person{:first-name Pablo, :last-name Neruda, :age 90, :occupation Poet}]
clojure.lang.MapEntry [3 #user.Person{:first-name Stefan, :last-name Zweig, :age 120, :occupation Author}]
)
请注意,每个条目都是一个MapEntry
。在您的尝试中,您将:age
应用于整个地图条目
(返回nil
),而不仅仅是人
我认为使用完全匿名函数进行分解是最简单的方法:
(defn get-120-year-old-guy
[peeps]
(filter (fn [[_ person]] (= (:age person) 120)) peeps))
产出:
who's 120?: ([3 #user.Person{:first-name Stefan, :last-name Zweig, :age 120, :occupation Author}])
@leetwinski指出了一个更为惯用的解决方案,它完全取消了显式函数:
(filter (comp #{120} :age val) people)
细分:
(defn get-120-year-old-guy [peeps]
(filter (comp ; And (comp)ose all three checks together
#{120} ; Then test if it's in the set of #{120}
:age ; Then get the age
val) ; Get the value from the MapEntry
peeps))
如果您查看外部映射中的第一项,您将看到每个项都是从字符串到Person的
clojure.lang.MapEntry
。键为“1”,值为个人记录:
> (first people)
["1"
{:first-name "John",
:last-name "Frusciante",
:age 50,
:occupation "Guitarist"}]
要对:age字段进行筛选,必须首先获取{key,value}对的值。一种方法是使用val函数在从Person map获取:age之前获取该值。您的过滤功能是:
(defn get-120-year-old-guy
[peeps]
(filter #(= (:age (val %)) 120) peeps)
)
> (println "who's 120?: " (get-120-year-old-guy people))
who's 120?: ([3 #challenges.anag.Person{:first-name Stefan, :last-name Zweig, :age 120, :occupation Author}])
另一个选项是使用clojure.lang.MapEntry
:
(defn get-120-year-old-guy
[peeps]
(filter (fn [[_ v]] (= (:age v) 120)) peeps)
)
在这里,您可以看到
(fn[[uv]]…
,其中
被用作未使用的键的占位符,或者只是(过滤器(comp.{120}:age val)人员)
@leetwinski-Ya,没错。老实说,我已经有两年没有写Clojure了。我太生疏了。哇。@Carcigenicate你换了什么?如果这不是秘密的话)@leetwinski我在学校学习信息安全,所以为了这门课程,我换了Python、C和汇编。我告诉你,从像Clojure这样流利、简洁的语言到C语言是很难的。