将映射 M 转换为映射数组 A,其中 M 中的键和值映射到 A 中元素中的新键



给定这样的地图:

{
 "keystring1" "valuestring1"
 "keystring2" "valuestring2"
 ...
}

如何将其转换为这样的地图数组:

[
 {
  :newKey1 "keystring1"
  :newKey2 "valuestring1"
 }
 {
  :newKey1 "keystring2"
  :newKey2 "valuestring2"
 }
 ...
]

根据我的研究,我认为reduce-kvassoc函数在这里应该很有用,但我还无法创建工作版本。

到目前为止,我得到的关闭是:

 (reduce-kv (fn [m k v]
   (merge m (assoc {} :newkey1 k) (assoc {} :newkey2 v)))
   []
   {"keystring1" "valuestring1", "keystring2" "valuestring2"})

这导致:

[{:newkey1 "keystring1"} {:newkey2 "valuestring1"} {:newkey1 "keystring2"} {:newkey2 "valuestring2"}]

我喜欢用for来做这样的事情。

(def m {"keystring1" "valuestring1"
        "keystring2" "valuestring2"})
> (for [[k v] m]
    {:newkey1 k
     :newkey2 v})
({:newkey1 "keystring1", :newkey2 "valuestring1"}
 {:newkey1 "keystring2", :newkey2 "valuestring2"})

如果确实需要,您可以强制将其作为向量:

> (vec (for [[k v] m]
         {:newkey1 k
          :newkey2 v}))
[{:newkey1 "keystring1", :newkey2 "valuestring1"}
 {:newkey1 "keystring2", :newkey2 "valuestring2"}]

这是一个使用 reduce-kv 的解决方案:

(def my-map
  {"keystring1" "valuestring1"
   "keystring2" "valuestring2"})
(reduce-kv
  (fn [acc k v] (conj acc {:newKey1 k :newKey2 v}))
  []
  my-map)

或使用zipmap

(mapv #(zipmap [:newKey1 :newKey2] %) my-map)

两者都产生这个:

=> [{:newKey1 "keystring1", :newKey2 "valuestring1"}
    {:newKey1 "keystring2", :newKey2 "valuestring2"}]

还有一个,为了完整起见:

user> (map (partial zipmap [:new-key1 :new-key2]) data)
;;=> ({:new-key1 "keystring1", :new-key2 "valuestring1"} 
;;    {:new-key1 "keystring2", :new-key2 "valuestring2"})

user> (map zipmap (repeat [:new-key1 :new-key2]) data)
;;=> ({:new-key1 "keystring1", :new-key2 "valuestring1"} 
;;    {:new-key1 "keystring2", :new-key2 "valuestring2"})

最新更新