Clojure:如何迭代对象列表以创建(报告)对象?将对象列表转换为键/ val哈希

时间:2016-09-28 15:53:34

标签: clojure

我正在尝试迭代列表,以便根据其内容创建报告。你如何转换看起来像这样的东西:

(
    {
        :_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
    )
)

5 个答案:

答案 0 :(得分:3)

(defn report [items]
  (into {} (map (fn [{id :_id :as m}] [(keyword id) m]) items)))

答案 1 :(得分:1)

我想我得到了它,但我不确定这是最干净的语法:

(defn createReportFromObjArray [inputarray]

    (reduce (fn [returnobj elementobj]

                (let [_id (get-in elementobj [:_id])
                      keyword (keyword _id)]

                    (assoc returnobj keyword elementobj)
                )
            )
            {}
            inputarray)
)

答案 2 :(得分:1)

您应该使用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"}]}

答案 3 :(得分:1)

只是稍微改善一个已经很好的答案:

(into {} (map (juxt (comp keyword :_id) identity) input))

答案 4 :(得分:0)

非常简单,用密钥创建一个地图,然后将它们合并在一起:

(defn rpt [o]
  (apply merge 
    (map #(array-map (keyword (:_id %)) %) o)))