我一直在与这个小小的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))
有人能找到更好的解决方案吗?
答案 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
。
如果可以保证输入参数格式,可以进一步缩小为:
(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)))