我有一些XML文件,我已经成功地使用这些文件来产生一些针对每月时间段的计数,尽管我需要将其转换为稍微压缩它。我生成的列表是通过下面的一些for循环完成的(例如),我将它以下面的格式输出到表中:
LEVEL1 (for [forloop LVL4_records]
{
:MONTH(get (split (:date forloop) #"-") 1)
:LEVEL(:lvl forloop)
})
group-by-date(group-by :MONTH LEVEL1)
LEVEL1_2 (for [forloop2 group-by-date]
{
:MONTH(:MONTH (first(second forloop2)))
:LEVEL(:LEVEL(first (second forloop2)))
:TOTAL(count (distinct (second forloop2)))
})
月 - LEVEL - COUNT
扬-------- --------- 01 10
扬-------- --------- 02 55
扬-------- --------- 03 112
二月-------- --------- 01 23
二月-------- --------- 02 30
二月-------- --------- 03 268
我想要做的是将其组织成一个月份不同且级别为主要标题的方式:
月 - 级别01 - 级别02--级别03
扬-------- 10 ------------ 55 ------------- 112
二月-------- 23 ------------ 30 ------------- 268
我猜我需要另一个循环来运行不同的级别,并使月份不同虽然我已经尝试了一些东西而且它们没有工作...到目前为止的代码在第一个表,所以在将数据重新格式化为第二种样式时,非常感谢这里的任何帮助。
答案 0 :(得分:2)
从这里的数据中取出每组LEVEL
月 - LEVEL - COUNT
扬-------- --------- 01 10
扬-------- --------- 02 55
扬-------- --------- 03 112
二月-------- --------- 01 23
二月-------- --------- 02 30
二月-------- --------- 03 268
将它们转换为map
,从:COUNT
转换为:MONTH
,然后使用您提供的格式通过这些地图打印表格。
e.g。地图应该是这样的
{:LEVEL 1 :DATA [{:MONTH "Jan" :COUNT 10}
{:MONTH "Feb" :COUNT 23}]
:LEVEL 2 :DATA [{:MONTH "Jan" :COUNT 55}
{:MONTH "Feb" :COUNT 30}]
:LEVEL 3 :DATA [{:MONTH "Jan" :COUNT 112}
{:MONTH "Feb" :COUNT 268}]
甚至
{1 {"Jan" 10
"Feb" 23}
2 {"Jan" 55
"Feb" 30}
3 {"Jan" 112
"Feb" 268}
答案 1 :(得分:1)
这是一件很棘手的事情,但它是可行的。这就是我想出的:
(def by-level
{1 {"Jan" 10, "Feb" 23}
2 {"Jan" 55, "Feb" 30}
3 {"Jan" 112, "Feb" 268}})
(def by-month
(reduce (fn [table [level months]]
(apply merge-with merge table (map (fn [[month count]]
{month {level count}})
months)))
{}
by-level))
; by-month =>
{"Jan" {3 112, 2 55, 1 10}, "Feb" {3 268, 2 30, 1 23}}
(这是Albus回答的问题 - 他指出你的地图应该用关卡作为关键字排列,因为这就是你的XML文件的布局方式。)
reduce
是for循环的功能对应物。我们在这里使用它来遍历我们的表(by-level
)并从空地图by-month
开始构建一个新表{}
。在每次迭代中,我们选择by-level
中的一个条目(例如,{1 {"Jan" 10, "Feb" 23}}
)并在每个月份计数对上使用map
来返回{{1}形式的地图列表1}}(第一个数字是级别(1),第二个数字是计数(10))。然后我们{"Jan" {1 10}}
将这些“月到水平/计数”映射到我们正在进行的表格中。一旦我们遍历原始地图中的每个“级别”,我们最终会得到每个月的地图到每个级别的次要地图及其数量。
“merge
”起初可能看起来有点奇怪。我们进行辅助apply merge-with merge
操作的原因是我们正在处理嵌套映射。如果我们刚刚说过merge
,apply merge
和"Jan"
将被“覆盖”,每次传递到下一个级别,最后我们会有类似{{1}的内容}。使用"Feb"
,我们会这样做,以便如果{"Jan" {3 112}, "Feb" {3 268}}
之类的密钥已经存在,我们merge-with
"Jan"
的现有值将带有新值 - 我们的值'重新使用merge
之类的地图,所以我们不是替换我们拥有的值,而是通过合并新地图和新的等级/数组合来“添加”。
现在,您可以使用"Jan"
从地图中获取单个值,例如:
{2 55}
或者您可以将get
留出来,只需将地图本身用作函数:
(get (get by-month "Jan") 3) ;=> 112 (January, Level 3)