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

时间:2013-10-11 18:38:53

标签: clojure

我一直在与这个小小的Clojure片段搏斗,但一直觉得有一种更惯用,更简单的方法。

期望的行为;转换“1” - > true,“0” - >假。否则按原样返回参数:

(= (mapper {:column 0} ["monkey" "stuff"]) "monkey")
(= (mapper {:column 0} ["1" "stuff"]) true)
(= (mapper {:column 0} ["0" "stuff"]) false)

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

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

第二次尝试:

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

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

2 个答案:

答案 0 :(得分:5)

如果:column密钥是标准密钥,则可以使用destructuring

(defn mapper [{c :column :or {c 0}}
              {item c}]
  ({"1" true "0" false} item item))


工作原理:

({"1" true "0" false} item item)

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

{c :column :or {c 0}}

此解构表单使用:column作为传递到函数第一个参数的项的键。 (在这种情况下,这是您的{:column 0}散列映射。)当:or键不存在或参数不是有效集合时,可选的:column关键字允许使用默认值(例如,零,数字,日期等)。 c现在将包含:column键的值或默认值0。

{item c}

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


Code Golf:

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

(fn [{i :column} {x i}] ({"1" true "0" false} x x))


答案 1 :(得分:3)

我会选择更长时间(也更具可读性)的实现:

(defn mapper [{c :column} row]
    (let [v (row c)]
      (condp = v
             "1" true
             "0" false
             v)))