如何在Clojure中迭代嵌套的dict/hash-map来自定义/变换我的数据结构?

ali*_*dry 0 clojure

我有一些看起来像这样的东西:

{:person-123 {:xxx [1 5]
              :zzz [2 3 4]}
 :person-456 {:yyy [6 7]}}
Run Code Online (Sandbox Code Playgroud)

我想改变它,看起来像这样:

[{:person "123" :item "xxx"}
 {:person "123" :item "zzz"}
 {:person "456" :item "yyy"}]
Run Code Online (Sandbox Code Playgroud)

这是一个类似flatten的问题,我知道我可以通过调用name它们将关键字转换为字符串,但我无法通过方便的方式来实现这一点.

这就是我做的方式,但它似乎不优雅(嵌套for循环,我在看着你):

(require '[clojure.string :refer [split]])
(into [] 
      (apply concat
             (for [[person nested-data] input-data]
                  (for [[item _] nested-data]
                       {:person (last (split (name person) #"person-"))
                        :item (name item)}))))
Run Code Online (Sandbox Code Playgroud)

Shl*_*omi 7

你的解决方案也不错,对于嵌套的for循环,for实际上支持嵌套循环,所以你可以把它写成:

(vec 
  (for [[person nested-data] input-data
       [item _] nested-data]
    {:person (last (clojure.string/split (name person) #"person-"))
     :item   (name item)}))
Run Code Online (Sandbox Code Playgroud)

就个人而言,我倾向于for专门用于此目的(嵌套循环),否则我通常会更熟悉map等等.但这仅仅是个人偏好.

我也非常同意@ amalloy对这个问题的评论,我会付出一些努力来开始寻找一个更好看的地图结构.