【问题标题】:Clojure / Clojurescript: group-by a map on multiple valuesClojure / Clojurescript:按多个值的映射分组
【发布时间】:2017-12-28 15:44:22
【问题描述】:

给定一个数据结构,我想重新构造它以按嵌套值之一进行分组。这些值是向量,每当我遇到多个值时,我都会陷入困境。

给定一个这样的地图向量:

(def tools 
 [{:name "A",
   :config
   {:accepts ["id"],
    :classes ["X"]}}
  {:name "B",
   :config
   {:accepts ["id"],
    :classes ["X", "Y"]
    }}])

我可以几乎得到我想要的——通过运行group-by

(group-by #(get-in % [:config :classes]) tools)

但它以:classes 中的整个向量作为键。

 {["X"] [{:name "A", 
          :config {:accepts ["id"], 
                   :classes ["X"]}}], 
  ["X" "Y"] [{:name "B", 
              :config {:accepts ["id"], 
                       :classes ["X" "Y"]}}]}

我真正想要的是每个类复制一次值,如下所示:

 {"X" [{:name "A"
        :config {:accepts ["id"]
                 :classes ["X"]}}
       {:name "B"
        :config {:accepts ["id"]
                 :classes ["X" "Y"]}}]
  "Y" [{:name "B"
        :config {:accepts ["id"]
                 :classes ["X" "Y"]}}]}

鉴于我在 classes 中有多个值,我不太确定如何处理。

工作 repl 演示:https://repl.it/@YoYehudi/FamiliarDisguisedXiphiasgladius

【问题讨论】:

    标签: clojure clojurescript


    【解决方案1】:

    这是一种使用嵌套reduce 的方法:

    (defn aggregate-classes [m tool]
      (->> (get-in tool [:config :classes])
           (reduce (fn [acc elem]
                     (update acc elem conj tool))
                   m)))
    
    (reduce aggregate-classes {} tools)
    =>
    {"X" ({:name "B", :config {:accepts ["id"], :classes ["X" "Y"]}} {:name "A", :config {:accepts ["id"], :classes ["X"]}}),
     "Y" ({:name "B", :config {:accepts ["id"], :classes ["X" "Y"]}})}
    

    【讨论】:

      【解决方案2】:
      (apply merge-with into {}
             (for [tool tools
                   class (get-in tool [:config :classes])]
               {class [tool]}))
      

      【讨论】:

      • 不错!这也比reduce 版本快很多
      猜你喜欢
      • 1970-01-01
      • 2012-06-12
      • 2015-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多