Clojure - 使用过滤器

时间:2014-03-13 16:25:07

标签: loops for-loop clojure filter

我正在尝试迭代地图来计算单个事件的特定事件,尽管我在使用过滤器时遇到了一些问题,如下所示。我想要做的是过滤和计算每个“ORDER_CATEGORY”的特定实例,这些实例出现在多个级别-1,2等等。我可以迭代几个月并打印但是过滤器和我对ORDER_CATEGORY的计数只是似乎不适合我。

 GROUPED_BY_MONTH(group-by :MONTH CON)

 ALL (for [flop GROUPED_BY_MONTH] {
    :MONTH  (:MONTH (first (second flop)))
    :ORDER1 (count (filter #(= "1" (:ORDER_CATEGORY %)) flop))
    :ORDER2 (count (filter #(= "2" (:ORDER_CATEGORY %)) flop))
})

我正在处理XML文件,我已成功将其汇总到一个连锁列表中,并按如下方式分组:

[“01”[{:MONTH“01”,:ORDER_CATEGORY“1”} {:MONTH“01”,:ORDER_CATEGORY“1”} {:MONTH“01”,:ORDER_CATEGORY“2”}]] [“02”[{:MONTH“02”,:ORDER_CATEGORY“1”} {:MONTH“02”,:ORDER_CATEGORY“2”} {:MONTH“02”,:ORDER_CATEGORY“2”}]]

因此,我希望有:

MONTH ORDER1 ORDER2

01 -------- 2 -------------- 1

02 -------- 1 -------------- 2

这可能是一个相对简单的修复,我忽略了,所以感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

我首先将数据转换为:

user=> (pprint x)
[{:MONTH "01", :ORDER_CATEGORY "1"}
 {:MONTH "01", :ORDER_CATEGORY "1"}
 {:MONTH "01", :ORDER_CATEGORY "2"}
 {:MONTH "02", :ORDER_CATEGORY "1"}]

并使用功能:

user=> (defn inc1 [x] (if x (inc x) 1))
user=> (reduce (fn [acc {:keys [MONTH ORDER_CATEGORY]}]
                     (update-in acc [[MONTH ORDER_CATEGORY]] inc1)) {} x)
{["02" "1"] 1, ["01" "2"] 1, ["01" "1"] 2}

键是[月类别],值是订单数量。

答案 1 :(得分:1)

你的for循环不起作用,因为你已将这样的地图条目绑定到flop

["01" [{:MONTH "01", :ORDER_CATEGORY "1"} ...]]

您的过滤器表达式将其作为输入:

(filter #(= "1" (:ORDER_CATEGORY %)) flop)

这不起作用,因为:ORDER_CATEGORY不会返回某事。适用于"01",也适用于序列[{:MONTH ...} ...]

鉴于您绑定到flop的是MapEntry,您可以使用val来解决此问题:

(filter #(= "1" (:ORDER_CATEGORY %)) (val flop))

电子。 G:

(for [flop GROUPED_BY_MONTH]
  {:MONTH  (:MONTH (first (second flop)))
   :ORDER1 (count (filter #(= "1" (:ORDER_CATEGORY %)) (val flop)))
   :ORDER2 (count (filter #(= "2" (:ORDER_CATEGORY %)) (val flop)))})
=> ({:MONTH "01", :ORDER1 2, :ORDER2 1} {:MONTH "02", :ORDER1 1, :ORDER2 0})

您还可以使用析构函数来使代码更清晰:

(for [[month maps] GROUPED_BY_MONTH]
  {:MONTH month
   :ORDER1 (count (filter #(= "1" (:ORDER_CATEGORY %)) maps))
   :ORDER2 (count (filter #(= "2" (:ORDER_CATEGORY %)) maps))})
=> ({:MONTH "01", :ORDER1 2, :ORDER2 1} {:MONTH "02", :ORDER1 1, :ORDER2 0})

请注意,一般来说,这种解决方案更有利:

(reduce (fn [acc {:keys [MONTH ORDER_CATEGORY]}]
          (update-in acc [MONTH ORDER_CATEGORY] 
                     (fnil inc 0)))
        {} CON)
=> {"02" {"1" 1}, "01" {"2" 1, "1" 2}}

它返回month->order-category->count的地图,该地图独立于输入集中存在的订单类别和月份的种类和类型。

电子。 G。

(reduce (fn [acc {:keys [MONTH ORDER_CATEGORY]}]
          (update-in acc [MONTH ORDER_CATEGORY]
                     (fnil inc 0)))
        {} (conj CON
                 {:MONTH "01" :ORDER_CATEGORY "foo"}
                 {:MONTH "02" :ORDER_CATEGORY "foo"}
                 {:MONTH "02" :ORDER_CATEGORY "bar"}
                 {:MONTH "02" :ORDER_CATEGORY "1"}))
=> {"02" {"bar" 1, "foo" 1, "1" 2}, "01" {"foo" 1, "2" 1, "1" 2}}

但是,您应该知道,如果ORDER_CATEGORY的计数为0,则结果中不会关联任何值。