【问题标题】:clojure reduce a seq of maps to a map of vectorsclojure 将一系列映射简化为向量映射
【发布时间】:2013-09-27 17:38:19
【问题描述】:

我想减少以下seq:

({0 "Billie Verpooten"}
 {1 "10:00"}
 {2 "17:00"}
 {11 "11:10"}
 {12 "19:20"})

{:name "Billie Verpooten"
 :work {:1  ["10:00" "17:00"]
        :11 ["11:10" "19:20"]}}

但我不知道这样做。

我在想一个使用解构的递归函数。

【问题讨论】:

  • 构建结果图背后的逻辑是什么?比如,你知道key为0的map映射到name,work number是怎么“加起来”的吗?如果您有一个任意函数可以获取映射并返回适当的键值对,那将可以。
  • 带有键 0 的映射确实总是映射到名称,并且映射的所有其余部分都包含需要连接的对(其中仅保留第一个键,作为一种 id)。

标签: recursion clojure hashmap


【解决方案1】:

在标准库中有一个函数可以将序列缩减为某种东西,它被称为reduce。尽管在您的特定情况下,似乎适合 remove 特殊情况键 0 首先和 partition 其余部分进入它们应该成为的条目对。

以下函数给出了您问题中描述的结果:

(defn build-map [maps]
  (let [entries (map first maps)
        key-zero? (comp zero? key)]
    {:name (val (first (filter key-zero? entries)))
     :work (reduce (fn [acc [[k1 v1] [k2 v2]]]
                     (assoc acc (keyword (str k1)) [v1 v2]))
                   {}
                   (partition 2 (remove key-zero? entries)))}))

【讨论】:

  • 啊哈!这是我在 clojure 词汇表中实际上错过的分区(我这周才开始)谢谢。
【解决方案2】:

为了多样化,这里是通过线程序列操作函数表达答案的不同方式:

user> (def data '({0 "Billie Verpooten"}
                  {1 "10:00"}
                  {2 "17:00"}
                  {11 "11:10"}
                  {12 "19:20"}))

user> {:name (-> data first first val) 
       :work (as-> data x 
                   (rest x) 
                   (into {} x) 
                   (zipmap (map first (partition 1 2 (keys x))) 
                           (partition 2 (vals x))))}

as-> 线程宏是 Clojure 1.5 的新功能,使表达这种函数更加简洁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多