我正在尝试使用 clojure map 了解一个简单的(如在其他语言中一样)工作流程。

基本上归结为:如何链接这些操作?

  • group-by : map 向量上的键
  • select-keys 在没有前一个键的剩余 map 上
  • group-by 再次(0..n 次)并选择键
  • count 最后的唯一键实例。

  • 另见我之前的问题:Aggregate and Count in Maps

    示例:

    给定一个 map 向量
    (def DATA [{:a "X", :b "M", :c "K", :d 10}
               {:a "Y", :b "M", :c "K", :d 20}
               {:a "Y", :b "M", :c "F", :d 30}
               {:a "Y", :b "P", :c "G", :d 40}])
    

    执行group-by
    (defn get-tree-level-1 [] (group-by :a DATA))
    

    生成按该特定键的值分组的映射。
    { X [{:a X, :b M, :c K, :d 10}],
      Y [{:a Y, :b M, :c K, :d 20}
         {:a Y, :b M, :c F, :d 30}
         {:a Y, :b P, :c G, :d 40}]}
    

    到现在为止还挺好。但是如果我想从数据中构建一个 树状结构 呢,这意味着选择剩余的键并忽略一些,选择 :b:c 并忽略 :d ,这将在下一级别产生:
    (def DATA2   [{ :X [{:b "M", :c "K"}],
                    :Y [{:b "M", :c "K"}
                        {:b "M", :c "F"}
                        {:b "P", :c "G"}]}])
    

    最后,计算剩余键的所有实例(例如,计算 :b -root 下 Y 键的所有唯一值):
    (def DATA3   [{ :X [{:M  1}],
                    :Y [{:M  2}
                        {:P  1}])
    

    我尝试在 select-keys 之后执行 group-by ,但第一步后结果为空:
    (defn get-proc-sums []
      (into {}
        (map
          (fn [ [k vs] ]
            [k (select-keys vs [:b :c])])
          (group-by :a DATA))))
    

    最佳答案

    重复应用 group-by 是错误的工具:它不能很好地与自身组合。相反,检查您的输入映射并将它们中的每一个转换为对您有用的格式(使用 formap ),然后减少它以构建树结构。这是一个简单的实现:

    (defn hierarchy [keyseq xs]
      (reduce (fn [m [ks x]]
                (update-in m ks conj x))
              {}
              (for [x xs]
                [(map x keyseq) (apply dissoc x keyseq)])))
    
    user> (hierarchy [:a :b :c] '[{:a "X", :b "M", :c "K", :d 10}
                                  {:a "Y", :b "M", :c "K", :d 20}
                                  {:a "Y", :b "M", :c "F", :d 30}
                                  {:a "Y", :b "P", :c "G", :d 40}])
    {"Y" {"P" {"G" ({:d 40})},
          "M" {"F" ({:d 30}),
               "K" ({:d 20})}},
     "X" {"M" {"K" ({:d 10})}}}
    

    这为您提供了所需的分层格式,其中包含所有 map 的列表,其中仅包含“剩余”键。由此,您可以计算它们、区分它们、删除 :d 键或任何您想要的东西,方法是编写另一个处理此映射的函数,或者通过调整上面的 reduce 函数或 for 理解中发生的事情。

    关于Clojure:将 group-by :key 与剩余键上的选择键链接起来,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36183706/

    10-12 12:29
    查看更多