【问题标题】:Clojure - How to apply a different function to each column?Clojure - 如何对每一列应用不同的函数?
【发布时间】:2014-07-04 18:33:28
【问题描述】:

我是 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 元素?


我将有兴趣阅读这两种方法的解决方案。

最后我会将数据放入地图中。我只是不确定是否要在获取此地图之前或之后进行转换。

【问题讨论】:

    标签: csv vector map clojure


    【解决方案1】:

    对序列使用map;地图使用merge-with

    user=> (map #(% %2) converters-1 row-1)
    ("John" 24)
    user=> (merge-with #(% %2) converters-2 row-2)
    {:name "John", :age 24}
    

    【讨论】:

    • merge-with 用于地图,太棒了!谢谢
    【解决方案2】:
    (map #(%1 %2) converters-1 row-1)
    ;; ("John" 24)
    

    如果(def row-2 {:name "John", :age "24"})(在您的示例中为整数)

    (for [x (keys converters-2)] ((converters-2 x) (row-2 x)))
    ;; ("John" 24)
    

    【讨论】:

    • 完美,干杯!我没有意识到 map 可以接受两个以上的参数,这很强大。
    • 对于map-approach的解决方案,忘了说我要获取一个map:(into {} (for [x (keys converters-2)] [x ((converters-2 x ) (row-2 x))] )) PS:我现在修改了我原来的问题来澄清这一点。
    【解决方案3】:

    我找到了 map 方法的解决方案,但它不如 Diego 的向量解决方案优雅。

    (into {} (map (fn [[k v]] 
        [k  ((converters-2 k) v)]
    ) row-2))
    

    这种地图方法有更简单的解决方案吗? 我是否缺少可以简化它的核心功能?

    编辑:阅读 Diego 的编辑,我也可以使用 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))
    

    好吧,现在它已经写好了,对于我的新手来说,它更难阅读和理解。

    到目前为止,矢量解决方案仍然是最好的。我会睁大眼睛寻找更好的地图解决方案;总有一天它可能会派上用场。

    【讨论】:

      猜你喜欢
      • 2020-03-08
      • 2021-10-25
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-13
      • 1970-01-01
      • 2016-04-23
      相关资源
      最近更新 更多