C'est un comportement attendu. (doseq [x ... y ...])
va itérer sur chaque élément dans y
pour chaque élément de x
.
Au lieu de cela, vous devez itérer sur la carte elle-même une fois. (seq some-map)
renvoie une liste de vecteurs à deux éléments, un pour chaque paire clé/valeur de la carte. (En réalité, il s'agit de clojure.lang.MapEntry
mais se comportent comme des vecteurs à 2 éléments).
user> (seq {:foo 1 :bar 2})
([:foo 1] [:bar 2])
doseq
peut itérer sur cette séq comme n'importe quelle autre. Comme la plupart des fonctions de Clojure qui travaillent avec des collections, doseq
appels internes seq
sur votre collection avant de l'itérer. Vous pouvez donc simplement faire ceci :
user> (doseq [keyval db] (prn keyval))
[:subprotocol "mysql"]
[:username "usr"]
[:classname "com.mysql.jdbc.Driver"]
[:subname "//100.100.100.100:3306/clo"]
[:password "pwd"]
Vous pouvez utiliser key
et val
ou first
et second
ou nth
ou get
pour obtenir les clés et les valeurs de ces vecteurs.
user> (doseq [keyval db] (prn (key keyval) (val keyval)))
:subprotocol "mysql"
:username "usr"
:classname "com.mysql.jdbc.Driver"
:subname "//100.100.100.100:3306/clo"
:password "pwd"
De manière plus concise, vous pouvez utiliser la déstructuration pour lier chaque moitié des entrées de la carte à des noms que vous pouvez utiliser dans la fonction doseq
la forme. C'est idiomatique :
user> (doseq [[k v] db] (prn k v))
:subprotocol "mysql"
:username "usr"
:classname "com.mysql.jdbc.Driver"
:subname "//100.100.100.100:3306/clo"
:password "pwd"