本文介绍了如何迭代映射键和值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的地图,我想迭代:

I have the following map which I want to iterate:

(def db {:classname "com.mysql.jdbc.Driver" 
         :subprotocol "mysql" 
         :subname "//100.100.100.100:3306/clo" 
         :username "usr" :password "pwd"})

我尝试过以下操作,但不是打印键和值一次以各种组合打印键和值:

I've tried the following, but rather than printing the key and value once, it repeatedly prints the key and values as various combinations:

(doseq [k (keys db) 
        v (vals db)] 
  (println (str k " " v)))

,但Brian's(见下文)更合乎逻辑。

I came up with a solution, but Brian's (see below) are much more logical.

(let [k (keys db) v (vals db)] 
  (do (println (apply str (interpose " " (interleave k v))))))


推荐答案

这是预期的行为。 (doseq [x ... y ...])将迭代 y 中的每个项目 x

That's expected behavior. (doseq [x ... y ...]) will iterate over every item in y for every item in x.

而是应该遍历地图本身一次。 (seq some-map)将返回两个项目向量的列表,其中一个用于地图中的每个键/值对。 (真的他们 clojure.lang.MapEntry ,但表现得像2项目的向量。)

Instead, you should iterate over the map itself once. (seq some-map) will return a list of two-item vectors, one for each key/value pair in the map. (Really they're clojure.lang.MapEntry, but behave like 2-item vectors.)

user> (seq {:foo 1 :bar 2})
([:foo 1] [:bar 2])


b $ b

doseq 可以像任何其他一样迭代该seq。像Clojure中使用集合的大多数函数一样, doseq 在迭代之前在集合中内部调用 seq 。所以你可以这样做:

doseq can iterate over that seq just like any other. Like most functions in Clojure that work with collections, doseq internally calls seq on your collection before iterating over it. So you can simply do this:

user> (doseq [keyval db] (prn keyval))
[:subprotocol "mysql"]
[:username "usr"]
[:classname "com.mysql.jdbc.Driver"]
[:subname "//100.100.100.100:3306/clo"]
[:password "pwd"]

您可以使用 val nth get 获取这些向量中的键和值。

You can use key and val, or first and second, or nth, or get to get the keys and values out of these vectors.

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"


b $ b

更简洁地说,你可以使用解构来将每一半的映射条目绑定到一些可以在 doseq 中使用的名称。这是惯用的:

More concisely, you can use destructuring to bind each half of the map entries to some names that you can use inside the doseq form. This is idiomatic:

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"

这篇关于如何迭代映射键和值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 23:12