我需要一个非常快速和高效的方法,“转接”一个列表的地图在clojure。
假设我有:
(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))))))))))))基本上,我将所有值按月分组(组- by,注意,由于“应用juxt”,可以在多个键上键),这是列的键。这样,我推断出pc的唯一值,这将是行的关键。休息应该是不言而喻的。
你认为这是明确的服装设计吗?它能更高效、更清晰吗?
有用的链接:http://pramode.net/clojure/2010/06/01/lazy-sequences-in-clojure/
发布于 2011-11-21 20:14:11
惯用的clojure库(如clojure.java.jdbc)将提供这些长列表作为懒惰的seqs。这意味着您只需要足够的内存来包含单个行,再加上加载clojure和库的通常开销--前提是您从文件或数据库中获取数据,并将其写入流/db/任何东西,而不是全部保存在内存中。
对于您所要求的转换,给出了一个称为结果集的行(映射)集合,如下所示:
(interpose "\n"
(map (fn [row]
(clojure.string/join "|" (map row [:consumer :product ...]))
result-set)))将给您一个懒散的seq,您只需将其转储到一个文件中,就可以生成类似于所需的分离的数据。
增编:至于“快”--除非你的存储设置不寻常,否则这很可能比你的存储I/O快得多--而且它是直接的。
发布于 2011-11-22 13:45:54
这篇文章中没有提到通过处理这个数据集您想要达到的最终目标。至少,我不认为主要的想法是将1GB的数据放入HTML表中。因此,无法提供如何最好地实现这一目标的信息。仅仅重新排列相同的数据不会给出任何有意义的结果,也不会改变您以后要执行的操作的内存或访问要求。
首先,您显示的“基本”数据看起来可能是至少三个关系表上的联合查询的结果(如果适当的话)。通过SQL直接从这些表中获取信息可能要高效得多,在Clojure本身处理之前已经减少了信息量、过滤或排序。
如果不是,那么将数据正常化并将其存储在数据库中可能是一种选择,但这取决于您最终想要对数据做什么。
https://stackoverflow.com/questions/8217191
复制相似问题