gpt4 book ai didi

performance - Clojure: "transpose"有效地中型 map 列表

转载 作者:行者123 更新时间:2023-12-04 06:07:10 26 4
gpt4 key购买 nike

我需要一种非常快速有效的方法来“转置”clojure 中的 map 列表。

假设我有:

(def monthly-sales [{:month 1 :pc "A" :sales 100} 
{:month 2 :pc "B" :sales 200} ... {:month 12 :pc "Z" :sales 100}])

我需要有类似的东西:
 |PC|1|2|3|4|5|6|7|8|9|10|11|12|
|A|100||||||||||||
|Etc.|

我回答下面的问题:
 (let [grouped (group-by (apply juxt [:month]) monthly-sales)]
(apply str (interpose "\n"
(for [k (distinct (map :pc rows))]
(str "|" k "|" (clojure.string/join "|"
(for [n (range 1 13)]
(get (first (filter #(= (:pc %) k) (get grouped [n]))) :sale))))))))))))

基本上,我按月对所有值进行了分组(分组,请注意,由于“apply juxt”,它可以键入 1 个以上的键),这是该列的键。完成后,我推断出 pc 的唯一值,这将是该行的键。休息应该是不言自明的。

你认为这是明确的 clojurian 设计吗?能不能更高效、更清晰?

有用的链接:
http://pramode.net/clojure/2010/06/01/lazy-sequences-in-clojure/

最佳答案

惯用的 clojure 库(如 clojure.java.jdbc)将提供这些长列表作为惰性序列。这意味着您只需要足够的内存来包含单行以及加载 clojure 和库的通常开销 - 前提是您从文件或数据库中获取数据并将其写出到流/db/任何内容,而不是将其全部保存在内存。

至于您要求的转换,给定称为结果集的一系列行(映射),例如:

(interpose "\n"
(map (fn [row]
(clojure.string/join "|" (map row [:consumer :product ...]))
result-set)))

会给你一个懒惰的序列,你可以将它转储到一个文件中以产生类似 |你想要的分离数据。

附录:至于“快速”——除非您的存储设置不寻常,否则这可能比您的存储 I/O 快得多——而且很简单。

关于performance - Clojure: "transpose"有效地中型 map 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8217191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com