0

我需要根据 id 合并一组数组。

示例数据:

编辑:(更改为匹配 Clojure 数据结构)

 [{:id 1, :region :NA, :name :Test1, :OS :W}
  {:id 1, :region :EU, :name :Test2, :OS :W}
  {:id 2, :region :AS, :name :test3, :OS :L}
  {:id 2, :region :AS, :name :test4, :OS :M}]

变成:

编辑:(更改为匹配 Clojure 数据结构)

[{:id 1, :region [:NA :EU], :name [:Test1 :Test2] ,:OS [:W]}
 {:id 2, :region [:AS] :name [:test3 :Test4], :OS [:L :M]}]

| 是分隔符(可变) 如果可能的话,也想按字母顺序为好。

4

3 回答 3

0

您可以使用一些函数组合clojure.set(如果您将最外层的向量更改为设置)。具体clojure.set/index看起来很有希望。

于 2012-06-26T12:48:37.427 回答
0
(def data
 [{:id 1, :region :NA, :name :Test1, :OS :W}
  {:id 1, :region :EU, :name :Test2, :OS :W}
  {:id 2, :region :AS, :name :test3, :OS :L}
  {:id 2, :region :AS, :name :test4, :OS :M}])

(defn key-join
  "join of map by key , value is distinct."
  [map-list]
  (let [keys (keys (first map-list))]
       (into {} (for [k keys] [k (vec (set (map #(% k) map-list)))]))))

(defn group-reduce [key map-list]
  (let [gdata (group-by key map-list)]
    (into [] (for [[k m] gdata] (let [m (key-join m)](assoc m key ((key m) 0)))))))



user=> (group-reduce :id data)
[{:name [:Test2 :Test1], :OS [:W], :region [:EU :NA], :id 1} {:name [:test3 :test4], :OS [:L :M], :region [:AS], :id 2}]
于 2012-06-26T15:45:13.733 回答
0

您可以merge-with在示例中使用如下所示的功能。

首先,我们定义一些辅助函数

(defn collect [& xs]
  (apply vector (-> xs distinct sort)))

collect函数确保其中的项目xs是唯一的且已排序,并最终以向量的形式返回它们。

(defn merge-keys [k xs]
  (map #(apply merge-with collect %) (vals (group-by k xs))))

merge-keysxs首先通过主键(在您的情况下)对哈希映射进行分组,获取每个分组项目列表并使用上面的函数:id合并键的值。collect

(def xs [{:id 1, :region :NA, :name :Test1, :OS :W}
         {:id 1, :region :EU, :name :Test2, :OS :W}
         {:id 2, :region :AS, :name :test3, :OS :L}
         {:id 2, :region :AS, :name :test4, :OS :M}])

(merge-keys :id xs)
=> ({:id [1],
     :region [:EU :NA],
     :name [:Test1 :Test2],
     :OS [:W]}
    {:id [2],
     :region [:AS],
     :name [:test3 :test4],
     :OS [:L :M]})

但是请注意,即使是:id键现在也有与之关联的向量。您可以通过引入将单个值与键而不是向量相关联的语句来轻松地取消向量...ifcollect

(defn collect [& xs]
  (let [cs (apply vector (-> xs distinct sort))]
    (if (= 1 (count cs)) (first cs) cs)))

...或从那里获取结果merge-keys并执行

(map #(update-in % [:id] first) result)

这只会取消矢量:id地图条目

于 2012-09-02T00:35:32.013 回答