[英]Idiomatic way to wrap object into collection (if it's not a collection already) in Clojure?
I have (for instance) a mix of data structures such as {:name "Peter" :children "Mark"}
and {:name "Mark" :children ["Julia" "John"]
ie :children value is either a single string or a collection of strings.我有(例如)混合数据结构,例如
{:name "Peter" :children "Mark"}
和{:name "Mark" :children ["Julia" "John"]
即 :children 值是单个字符串或字符串的集合。 Other functions in my code expect that the value of :children is always a collection of strings, so I need to adapt the data for them.我的代码中的其他函数期望 :children 的值始终是字符串的集合,因此我需要为它们调整数据。
Of course I can use something like:当然,我可以使用类似的东西:
(defn data-adapter [m]
(let [children (:children m)]
(assoc m :children
(if (coll? children)
children
[children]))))
But is there a more idiomatic/laconic way?但是有没有更惯用/简洁的方式?
I think you will have to take no for an answer.我想你将不得不接受否定的答案。
(if (coll? x) x [x])
is about as terse and expressive as it gets. (if (coll? x) x [x])
尽可能简洁和富有表现力。 It's what people usually use for this problem (sometimes with sequential?
instead of coll?
).这是人们通常用于解决此问题的方法(有时使用
sequential?
而不是coll?
)。
cond->
enthusiasts like me sometimes try to use it in place of a simple conditional, but here it is no improvement: cond->
像我这样的爱好者有时会尝试使用它来代替简单的条件,但这里没有改进:
(cond-> x (not (coll? x)) vector)
In the context of your code, however, you can do a little better.但是,在您的代码上下文中,您可以做得更好一些。 A lookup and association is best expressed with
update
:查找和关联最好用
update
表示:
(defn data-adapter [m]
(update m :children #(if (coll? %) % [%])))
the only advice would be to abstract that logic to some function, to keep your actual business logic clean.唯一的建议是将该逻辑抽象为某个函数,以保持您的实际业务逻辑清晰。
(defn data-adapter [m]
(let [children (:children m)]
(assoc m :children (ensure-coll children))))
or, more concise, with update
:或者,更简洁,使用
update
:
(defn data-adapter [m]
(update m :children ensure-coll))
where ensure-coll
could be something like this:其中
ensure-coll
可能是这样的:
(defn iffun [check & {:keys [t f] :or {t identity f identity}}]
#((if (check %) t f) %))
(def ensure-coll (iffun coll? :f list))
(or whatever another implementation you like) (或您喜欢的任何其他实现)
user> (data-adapter {:children 1})
;;=> {:children (1)}
user> (data-adapter {:children [1]})
;;=> {:children [1]}
Perhaps not idiomatic, but laconic:也许不习惯,但简洁:
(flatten [x])
https://clojuredocs.org/clojure.core/flatten https://clojuredocs.org/clojure.core/flatten
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.