2

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

期望的行为;转换“1”-> 真,“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))

谁能找到更好的解决方案?

4

2 回答 2

5

如果:column键是标准的,则可以使用解构

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

这个怎么运作:

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

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

{c :column :or {c 0}}

这种解构形式:column用作传递给函数第一个参数的项的键。(在这种情况下,这是您的哈希图。)当键不存在或参数不是有效集合(例如 nil、数字、日期等)时{:column 0},可选:or关键字允许使用默认值。现在将包含键的值或默认值 0。:columnc:column

{item c}

由于作为第二个参数传递的集合是可索引的,因此您可以使用之前使用的相同形式。在前面的解构形式中命名的 varc包含 的值,:column它可用于索引到第二个参数,并将结果值分配给item


代码高尔夫:

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

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

于 2013-10-11T19:00:04.180 回答
3

我会选择更长(并且更具可读性?)的实现:

(defn mapper [{c :column} row]
    (let [v (row c)]
      (condp = v
             "1" true
             "0" false
             v)))
于 2013-10-11T21:46:35.583 回答