仅在Clojure中映射一组指定的值

Odi*_*din 2 clojure

我已经和这个小小的Clojure片段进行了一段时间的摔跤,但一直觉得有更惯用,更简单的方法.

期望的行为; 转换"1" - > true,"0" - > false.否则按原样返回参数:

(= (mapper {:column 0} ["monkey" "stuff"]) "monkey")
(= (mapper {:column 0} ["1" "stuff"]) true)
(= (mapper {:column 0} ["0" "stuff"]) false)
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试; 一种天真的命令式方法:

(defn mapper 
  [attr-map row]
  (let [x (row (:column attr-map))
        y ({"1" true "0" false} x)]
    (if (nil? y) 
      x
      y)))
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

(defn mapper 
  [attr-map row]
  ((comp #({"1" true "0" false} % %) row :column) attr-map))
Run Code Online (Sandbox Code Playgroud)

有人能找到更好的解决方案吗?

Jar*_*314 5

如果:column密钥是标准密钥,则可以使用解构.

(defn mapper [{c :column :or {c 0}}
              {item c}]
  ({"1" true "0" false} item item))
Run Code Online (Sandbox Code Playgroud)


这个怎么运作:

({"1" true "0" false} item item)
Run Code Online (Sandbox Code Playgroud)

可以将Hashmaps视为函数,其第一个参数是键,以检索值.此表单还接受第二个可选参数,该参数在hashmap不包含密钥时返回.

{c :column :or {c 0}}
Run Code Online (Sandbox Code Playgroud)

此解构形式:column用作传递到函数的第一个参数的项的键.(在这种情况下,这是您的{:column 0}hashmap.)可选:or关键字允许在:column密钥不存在时使用默认值,或者参数不是有效集合(例如,nil,数字,日期等).c现在将包含:column键的值或默认值0.

{item c}
Run Code Online (Sandbox Code Playgroud)

由于作为第二个参数传递的集合是可索引的,因此您可以使用先前使用的相同表单.在前一个解构形式中命名的var c包含值的值,:column它可以用于索引到第二个参数,并将结果值赋值给item.


代码高尔夫:

如果可以保证输入参数格式,可以进一步简化为:

(fn [{i :column} {x i}] ({"1" true "0" false} x x))
Run Code Online (Sandbox Code Playgroud)