我是Clojure的新手,为了好玩而玩它。
我正在阅读CSV文件,并希望对每列应用不同的功能。什么是优雅(简洁和可读)的方式来做到这一点? 我探讨了两种方法:
......
(def row-1 ["John", "24"])
...我想对每个元素应用不同的函数,并获得此结果:
["John", 24]
我想要使用的功能是:
(def converters-1 [identity, read-string])
是否有一种简单的方法可以将converters-1
函数应用于row-1
元素?
使用这种方法,我首先将每一行转换为地图:
(def row-2 {:name "John", :age "24"})
编辑:我想获得这张地图:
{:name "John", :age 24}
转换器也存储在地图中:
(def converters-2 {:name identity, :age read-string})
是否有一种简单的方法可以将正确的转换器应用于row-2
元素?
我将有兴趣阅读这两种方法的解决方案。
最后,我将数据放入地图中。我不确定在获取此地图之前或之后是否要进行转换。
答案 0 :(得分:4)
使用map
作为序列;使用merge-with
表示地图。
user=> (map #(% %2) converters-1 row-1)
("John" 24)
user=> (merge-with #(% %2) converters-2 row-2)
{:name "John", :age 24}
答案 1 :(得分:1)
(map #(%1 %2) converters-1 row-1)
;; ("John" 24)
if (def row-2 {:name "John", :age "24"})
(在你的例子中它是一个整数)
(for [x (keys converters-2)] ((converters-2 x) (row-2 x)))
;; ("John" 24)
答案 2 :(得分:0)
我找到了地图方法的解决方案,但它不如迭戈的矢量解决方案那么优雅。
(into {} (map (fn [[k v]]
[k ((converters-2 k) v)]
) row-2))
这种地图方法有更简单的解决方案吗? 我错过了一个可以简化它的核心功能吗?
编辑:阅读迭戈的编辑,我也可以使用keys
:
(into {} (map #(
[% ((converters-2 %) (row-2 %))] ; the key, and the converted value
) (keys row-2)))
但是我更喜欢之前的解决方案,因为它不需要评论:显而易见的是密钥和值的变化。另外,在此解决方案中,我只需要编写row-2
一次。
编辑2:如果我写(converters-2 k identity)
,那么我只需要指出需要转换的列。对于其他列(例如此处:name
),identity
是默认转换器。与矢量方法相比,这是一个优势。
编辑3:我使用update-in
找到了另一种地图方法解决方案:
(reduce #(update-in %1 [%2] (converters-2 %2)) row-2 (keys row-2))
嗯,既然已经写好了,对我的新手来说,阅读和理解起来比较困难。
到目前为止,矢量解决方案仍然是最好的。我会睁大眼睛寻找更好的地图解决方案;它可能会在某一天派上用场。