我试图遍历一个列表,以便在其内容上创建一个报告。如何转换像这样的内容:
(
{
:_id "123"
:keya "aaa"
:keyb "bbb"
}
{
:_id "456"
:keya "ccc"
:keyb "ddd"
}
{
:_id "789"
:keya "eee"
:keyb "fff"
}
)
变成了这样的东西?:
{
:123 {
:_id "123"
:keya "aaa"
:keyb "bbb"
}
:456 {
:_id "456"
:keya "ccc"
:keyb "ddd"
}
:789 {
:_id "789"
:keya "eee"
:keyb "fff"
}
}
我非常感谢你能提供的帮助。
编辑:我已经尽力了
(defn fetchAndReport [idarray]
(let [fetched_objs (mc/find-maps mongoconnection ncoll {:_id { "$in" idarray }})
bad_report (zipmap idarray fetched_objs) ;; mismatched keys with wrong objs - can't count on payload order
post_fetched_ids (map (fn [element] (get-in element [:_id])) fetched_objs)
long_way_report (zipmap post_fetched_ids fetched_objs)]
long_way_report
)
)
(defn report [items]
(into {} (map (fn [{id :_id :as m}] [(keyword id) m]) items)))
我想我明白了,但我不确定这是最干净的语法:
(defn createReportFromObjArray [inputarray]
(reduce (fn [returnobj elementobj]
(let [_id (get-in elementobj [:_id])
keyword (keyword _id)]
(assoc returnobj keyword elementobj)
)
)
{}
inputarray)
)
您应该使用Clojure内置的group-by
函数:
(ns clj.core
(:require [clojure.pprint :refer [pprint]] ))
(t/refer-tupelo)
(def x
[
{
:_id "123"
:keya "aaa"
:keyb "bbb"
}
{
:_id "456"
:keya "ccc"
:keyb "ddd"
}
{
:_id "789"
:keya "eee"
:keyb "fff"
}
] )
(def y (group-by #(:_id %) x))
(pprint y)
> lein run
{"123" [{:_id "123", :keya "aaa", :keyb "bbb"}],
"456" [{:_id "456", :keya "ccc", :keyb "ddd"}],
"789" [{:_id "789", :keya "eee", :keyb "fff"}]}
只是稍微改进一下已经很好的答案:
(into {} (map (juxt (comp keyword :_id) identity) input))
非常简单,用键创建一个映射,然后将它们合并在一起:
(defn rpt [o]
(apply merge
(map #(array-map (keyword (:_id %)) %) o)))