简体   繁体   English

如何在Clojure /脚本中迭代嵌套的PersistentArrayMap

[英]How to iterate nested PersistentArrayMap in Clojure/Script

After executing a query against the db, the return of the fuction is the list of maps: 对数据库执行查询后,函数的返回是映射列表:

({:id 1 :name "Book 1" :category "Drama"}
 {:id 2 :name "Book 2" :category "Drama"}
 {:id 3 :name "Book 3" :category "Poetry"}
 {:id 4 :name "Book 4" :category "Poetry"}
 {:id 5 :name "Book 5" :category "Fantasy"}
 {:id 6 :name "Book 6" :category "Fantasy"}
 {:id 7 :name "Book 7" :category "Fantasy"}
 {:id 8 :name "Book 8" :category "Science fiction"}
 {:id 9 :name "Book 9" :category "Science fiction"}
 {:id 10 :name "Book 10" :category "Science fiction"}
 ...)

So, I group data by category and group-by function returns a persistent array-map contains strs keys and vector of maps as vals: 因此,我按类别对数据进行分组,并且group-by函数返回一个持久的数组映射,其中包含strs键和映射向量作为val:

{"Fantasy" [{:category "Fantasy", :name "Book 5", :id 5} 
            {:category "Fantasy", :name "Book 6", :id 6} 
            {:category "Fantasy", :name "Book 7", :id 7}], 
 "Drama" [{:category "Drama", :name "Book 1", :id 1} 
          {:category "Drama", :name "Book 2", :id 2}], 
 "Poetry" [{:category "Poetry", :name "Book 3", :id 3} 
           {:category "Poetry", :name "Book 4", :id 4}], 
 "Science fiction" [{:category "Science fiction", 
                     :name "Book 8", 
                     :id 8} 
                    {:category "Science fiction", 
                     :name "Book 9", 
                     :id 9} 
                    {:category "Science fiction", 
                     :name "Book 10", 
                     :id 10}]}

Next, I do this: 接下来,我这样做:

(doseq [[k [{:keys [id name]} v]] data]
  (println k)
  (println id name))

The side-effect is: 副作用是:

Drama
1 Book1
Poetry
3 Book3
Fantasy
5 Book5
Science fiction
8 Book8

doseq returned only one value for each key . 每个密钥的doseq仅返回一个值

How can I get the rest of the values? 我如何获得其余的价值? The result must be: 结果必须是:

Drama
1 Book1
2 Book2
Poetry
3 Book3
4 Book4
Fantasy
5 Book5
6 Book6
7 Book7
Science fiction
8 Book8
9 Book9
10 Book10

you can just make an inner loop like this: 您可以像这样进行内部循环:

(doseq [[k vs] data]
  (println k)
  (doseq [{:keys [id name]} vs]
    (println id name)))

or using single doseq : 或使用单一doseq

(doseq [[k vs] data
        {:keys [id name] :as v} vs]
  (when (= v (first vs))
    (println k))
  (println id name))

also there is one more dirty way to print outer loop string once: 还有一种更脏的方法可以一次打印外循环字符串:

(doseq [[k vs] data
        :when (or (println k) true)
        {:keys [id name] :as v} vs]
  (println id name))

or even like this: 甚至像这样:

(doseq [[k vs] data
        {:keys [id name] :as v} (do (println k) vs)]
  (println id name))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM