且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何迭代映射键和值?

更新时间:2022-06-09 00:38:31

这是预期的行为。 (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"