简体   繁体   English

Clojure-使用过滤器

[英]Clojure - Using Filters

I am trying to iterate through a map to count specific occurances of individual events although I am having some trouble using a filter as below. 我正在尝试遍历地图以计算单个事件的特定发生次数,尽管在使用以下过滤器时遇到了一些麻烦。 What I want to do is filter and count the specific instances of each "ORDER_CATEGORY" which occur in a number of levels - 1, 2, and so on. 我想要做的是过滤并计算每个“ ORDER_CATEGORY”的特定实例,这些实例以多个级别(1、2等)出现。 I am able to iterate though the months and print but teh filter and count I have for the ORDER_CATEGORY's just doesnt seem to work for me. 我可以遍历月份并进行打印,但可以过滤并计算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))
})

I am working with XML files which I have successfully managed into one concatenated list and grouped as below: 我正在处理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"}]] [“ 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”}]]

Therefore, I would expect to have: 因此,我希望有:

MONTH ORDER1 ORDER2 MONTH ORDER1 ORDER2

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

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

This may be a relatively simple fix that I'm overlooking so thanks for the help in advance! 这可能是我忽略的相对简单的修复程序,因此感谢您的提前帮助!

I would first convert the data to: 我首先将数据转换为:

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

and use functions: 并使用功能:

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}

Key is [Month Category], value is the number of orders. 关键是[月份类别],值是订单数。

Your for loop does not work, because you have bound a map entry like this to flop 您的for循环不起作用,因为您已将这样的映射项绑定到flop

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

And your filter expressions take that as an input: 您的过滤器表达式会将其作为输入:

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

This will not work, because :ORDER_CATEGORY will neither return sth. 这将不起作用,因为:ORDER_CATEGORY都不会返回sth。 for "01" , nor for the sequence [{:MONTH ...} ...] . 表示"01" ,也不表示序列[{:MONTH ...} ...]

Given that what you have bound to flop is a MapEntry, you can use val to fix this: 鉴于绑定到flop是MapEntry,可以使用val来解决此问题:

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

E. 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})

You could also use destructoring, to make your code more clear: 您还可以使用析构函数使代码更清晰:

(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})

Notice that in general, this solution is more favorable: 请注意,通常,此解决方案更有利:

(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}}

It returns a map of month->order-category->count that works independently of the kinds and types of order categories and months present in the input set. 它返回一个month->order-category->count映射,该映射独立于输入集中存在的订单类别和月份的种类和类型。

E. 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}}

However you should be aware that in case of a count of 0 for an ORDER_CATEGORY , no value is associated in the result. 但是,您应该知道,如果ORDER_CATEGORY的计数为0,则结果中没有任何关联的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM