Is there a Clojure function which takes a map and returns a sequence of alternating keys and values?

StackOverflow https://stackoverflow.com/questions/12770359

  •  05-07-2021
  •  | 
  •  

Pregunta

Given a map {:a 1 :b [2,3]}, is there a built-in function which would return the sequence (:a 1 :b [2,3]).

The use case is applying an options map to a function which does map-destructured binding on the remainder of an argument list. Here's an example of this in core.cache. Here's a contrived example to illustrate:

(defn make-car [& {:as options}] (assoc options :car true))
(make-car :color "red" :speed "fast")
; => {:car true, :speed "fast", :color "red"}

Now if we want to manage the options separately and apply them to the function, we have a problem:

(def options {:color "red" :speed "fast"})
(apply make-car options)
; => {:car true, [:speed "fast"] [:color "red"]}

...because of course the seq of a map is a sequence of its key-value pairs. This is the best I've come up with:

(apply make-car (interleave (keys options) (vals options)))
; => {:car true, :speed "fast", :color "red"}

This is pretty awful. I know I could just make my own function to do this, but I'm surprised I haven't found something built-in. If there isn't something built-in, then I'd probably want to avoid destructuring argument lists like this in library code.

¿Fue útil?

Solución

How about this:

(reduce concat {:a 1 :b [2,3]})
(:a 1 :b [2 3])

Update based on the comment from amalloy. Apply is more efficient (at least in 1.4), and achieves the same result!

(apply concat {:a 1 :b [2,3]})
(:a 1 :b [2 3])
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top