Filter 一次迭代中的多个过滤器

Filter 一次迭代中的多个过滤器,filter,clojure,functional-programming,Filter,Clojure,Functional Programming,假设我有一个元组列表,如下所示: [["type_2" "val_x"] ["type_1" "val_y"] ["type_1" "val_z"]] 我想对它们进行过滤,这样我就有两个独立的集合,如下所示: [["type_2" "val_x"]] [["type_1" "val_y"] ["type_1" "val_z"]] 我可以运行两次过滤器。我想知道是否有可能通过函数式编程在一次迭代中获得相同的结果 这是所需的界面: (multiple-filter predicate_fn_

假设我有一个元组列表,如下所示:

[["type_2" "val_x"] ["type_1" "val_y"] ["type_1" "val_z"]]
我想对它们进行过滤,这样我就有两个独立的集合,如下所示:

[["type_2" "val_x"]] 

[["type_1" "val_y"] ["type_1" "val_z"]]
我可以运行两次过滤器。我想知道是否有可能通过函数式编程在一次迭代中获得相同的结果

这是所需的界面:

(multiple-filter predicate_fn_1 predicate_fn_2 coll)
虽然在您的情况下,
(VAL(先分组…
)可以正常工作,但它不是通用的。下面是应用多个筛选器的一种变体(多种可能的变体之一):

(defn classify [items & preds]
  (loop [[x & xs :as items] items
         res (repeat (count preds) [])]
    (if (empty? items)
      res
      (recur xs 
             (mapv #(if (% x) (conj %2 x) %2) preds res)))))
答复:

user> (classify [[:a 10] [:a 20] [:b 30] [:d 2] [:c 40] [:d 1]]
                #(= (first %) :a)
                #(= (first %) :b)
                #(= (first %) :d))
[[[:a 10] [:a 20]] [[:b 30]] [[:d 2] [:d 1]]]
或与reduce相同:

(defn classify [items & preds]
  (reduce (fn [res x] (mapv #(if (% x) (conj %2 x) %2) preds res))
          (repeat (count preds) [])
          items))

@leetwinski的
classify
函数无法满足您所需的接口;例如,下面是一个兼容的实现:

(defn multiple-filter [& preds-and-coll]
  (let [[preds coll] ((juxt drop-last last) preds-and-coll)]
    (mapv #(filterv % coll) preds)))
例如:

(multiple-filter (comp #{"type_1"} first)
                 (comp #{"type_2"} first)
                 [["type_2" "val_x"] ["type_1" "val_y"] ["type_1" "val_z"]])
;;=> [[["type_1" "val_y"] ["type_1" "val_z"]] [["type_2" "val_x"]]]

我没有将其作为一个单独的迭代来实现,因为这会使这个答案变得复杂,并且不会影响算法的复杂性,但是可以使用@leetwinski的单独迭代实现替换我使用
mapv
filterv
的实现[“type_1”“val_z”]])您应该做什么want@m33lky请您将代码块移到它们自己的行中,并在行的开头添加四个空格以使它们成为代码块,然后从它们周围删除“`”。我通常会解决这些格式问题,但存在一个问题,因此我无法用其他挂起的编辑来编辑问题,因此我无法修复t他为您设置了格式。@Arthurlfeldt将所有内容都放在代码块中,而不是勾选。您还可以编写
(应用分类[:A10][:A20][:B30][:D2][:C40][:D1]](map#(comp{%}first)[:a:b:d])
@SamEstep为什么不将其作为一个单独的答案添加?@m33lky,因为我的评论只是关于函数用法的说明,与实现无关。但是,我也相信实现可以改进,所以我也添加了我自己的答案。所以事实上它是
(count preds)
传递集合?而问题(至少在我理解的情况下),是关于一个过滤器中的多个过滤器pass@leetwinski是的,我在回答中部分提到了这一点:在我的实现中,外循环迭代
preds
,内循环迭代
coll
,而在您的实现中,外循环迭代
,内循环迭代
predse> 。它不会影响算法的复杂性,所以我保留了它的原样,但如果必要的话,可以很容易地在您的实现中进行交换。哦。你是对的。我想这一个更好。