在Clojure中将对象包装到集合(如果它还不是集合)的惯用方法?
例如,我有一个混合的数据结构,如{:name-Peter:children-Mark}和{:name-Mark:children[Julia-John]即:children值是单个字符串或字符串的集合。我代码中的其他函数期望:children的值始终是字符串的集合,因此我需要为它们调整数据。 当然,我可以使用类似于:在Clojure中将对象包装到集合(如果它还不是集合)的惯用方法?,clojure,Clojure,例如,我有一个混合的数据结构,如{:name-Peter:children-Mark}和{:name-Mark:children[Julia-John]即:children值是单个字符串或字符串的集合。我代码中的其他函数期望:children的值始终是字符串的集合,因此我需要为它们调整数据。 当然,我可以使用类似于: (defn data-adapter [m] (let [children (:children m)] (assoc m :children
(defn data-adapter [m]
(let [children (:children m)]
(assoc m :children
(if (coll? children)
children
[children]))))
但是有没有更惯用/简洁的方法呢?我想你的答案应该是否定的 如果coll?x[x]是最简洁、最有表现力的,那么人们通常用sequential?而不是coll?来解决这个问题 cond->像我这样的狂热者有时会尝试使用它来代替简单的条件,但在这里没有改进:
(cond-> x (not (coll? x)) vector)
但是,在您的代码上下文中,您可以做得更好。查找和关联最好用更新来表示:
我想你得接受否定的回答 如果coll?x[x]是最简洁、最有表现力的,那么人们通常用sequential?而不是coll?来解决这个问题 cond->像我这样的狂热者有时会尝试使用它来代替简单的条件,但在这里没有改进:
(cond-> x (not (coll? x)) vector)
但是,在您的代码上下文中,您可以做得更好。查找和关联最好用更新来表示:
唯一的建议是将该逻辑抽象为某个函数,以保持实际业务逻辑的干净
(defn data-adapter [m]
(let [children (:children m)]
(assoc m :children (ensure-coll children))))
或者,更简洁地说,有更新:
其中,coll可以是这样的:
(defn iffun [check & {:keys [t f] :or {t identity f identity}}]
#((if (check %) t f) %))
(def ensure-coll (iffun coll? :f list))
或者任何你喜欢的其他实现
user> (data-adapter {:children 1})
;;=> {:children (1)}
user> (data-adapter {:children [1]})
;;=> {:children [1]}
唯一的建议是将该逻辑抽象为某个函数,以保持实际业务逻辑的干净
(defn data-adapter [m]
(let [children (:children m)]
(assoc m :children (ensure-coll children))))
或者,更简洁地说,有更新:
其中,coll可以是这样的:
(defn iffun [check & {:keys [t f] :or {t identity f identity}}]
#((if (check %) t f) %))
(def ensure-coll (iffun coll? :f list))
或者任何你喜欢的其他实现
user> (data-adapter {:children 1})
;;=> {:children (1)}
user> (data-adapter {:children [1]})
;;=> {:children [1]}