Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 如何使用varargs进行筛选?_Clojure_Functional Programming - Fatal编程技术网

Clojure 如何使用varargs进行筛选?

Clojure 如何使用varargs进行筛选?,clojure,functional-programming,Clojure,Functional Programming,我有一张用户及其喜爱乐队的地图: (def data { :David {"Tribalistas" 3.0 "Daft Punk" 5.0 "Lorde" 4.0 "Fall Out Boy" 1.0} :Matt {"Imagine Dragons" 3.0 "Daft Punk" 4.0 "Lorde" 4.0 "Fall Out Boy" 1.0} :Ben {"Kacey Mu

我有一张用户及其喜爱乐队的地图:

(def data
  {
    :David {"Tribalistas" 3.0
       "Daft Punk" 5.0
       "Lorde" 4.0
       "Fall Out Boy" 1.0}

    :Matt {"Imagine Dragons" 3.0
      "Daft Punk" 4.0
      "Lorde" 4.0
      "Fall Out Boy" 1.0}

    :Ben {"Kacey Musgraves" 4.0
     "Imagine Dragons" 3.0
     "Lorde" 3.0
     "Fall Out Boy" 1.0}
} )

我需要过滤有两个共同关键点的结果,在本例中是band1和band2

(defn common-ratings [band1 band2 ratings]
  (filter #(and ((second %) band1) ((second %) band2)) ratings))


(common-ratings "Daft Punk" "Lorde" data) ; should return David and Matt lines
但是现在,我需要在varargs中变换波段,我尝试使用如下方法:

apply and...
因此,我可以使用如下函数:

(common-ratings "Daft Punk" "Lorde" "Another band" "Another Band2" data)
但它不起作用


提前感谢

选项之一是将
宏包装到函数中:

(defn and-fn [x y] (and x y))
(defn and-multi [& args]
  (reduce #(and %1 %2) true args)) ; initial value is needed for invocation with no args
然后您可以使用
reduce
而不是
apply
来获得相同的结果:

(reduce and-fn [true true true false]) ; => false
为方便起见,可以将last reduce包装到另一个函数中:

(defn and-fn [x y] (and x y))
(defn and-multi [& args]
  (reduce #(and %1 %2) true args)) ; initial value is needed for invocation with no args
现在,它的行为将非常类似于正常的
宏:

(and-multi) ; => true
(and-multi false true) ; => false
(apply and-multi [true true true]) ; => true
它甚至与ARG的评估具有相同的行为:

(and false (range)) ; => false (despite of second param being infinite sequence)
(and-multi false (range)) ; => false
  • 如前所述,
    是一个宏,因此不能作为 函数、
    应用
    或任何其他函数
  • 最接近的标准函数是
    
由于带区数量未知,请将其作为集合传递:

(defn common-ratings [bands ratings]
  (filter #(every? (val %) bands) ratings))
。。。在这里,我将第二个
替换为,以表明我们正在处理地图条目

比如说,

(common-ratings ["Daft Punk" "Lorde"] data)
;([:David {"Tribalistas" 3.0, "Daft Punk" 5.0, "Lorde" 4.0, "Fall Out Boy" 1.0}] [:Matt {"Imagine Dragons" 3.0, "Daft Punk" 4.0, "Lorde" 4.0, "Fall Out Boy" 1.0}])
如果要将
标注栏
作为单个参数传递,请将其放在最后,以将其作为rest参数捕获:

(defn common-ratings [ratings & bands]
  ... )
。。。你这样称呼它:

(common-ratings data "Daft Punk" "Lorde")

。。。效果和以前一样

谢谢大家,我的最终解决方案非常接近@Thumbnail solution:

(defn common-ratings [& bands] (filter #(every? (second %) bands) data))

你能添加你期望的输入和输出,以及你迄今为止所做的尝试吗?每次我都想申请,结果证明有一种更干净的方法可以做到这一点。一个示例调用和结果会有很大帮助
#((第二个r)%)
就是
(第二个r)
@amalloy哎哟!谢谢。非常感谢大家,我的最终解决方案是:
(defn通用评级[&bands](过滤#(每秒%)bands)数据))
@renanresmartins不要将答案作为对其他人答案的评论发布。回答您自己的问题是完全可以接受的,这样将来的读者会发现它,但请将其作为答案而不是对其他人答案的评论。对不起,函数只接收x和y,如何将true false作为参数传递?thanks@renanreismartins这就是为什么使用了
reduce
而不是
apply
。我用更多的例子更新了答案。