使用向量中的参数应用具有多个参数的函数

apply function with multiple parameter with arguments from a vector

我有一个函数,它接受三个参数 somefunction [param1 param2 param3] 和一个带有值的向量 [val1 val2 val3 val4 ...] 我想重复调用 somefunction ,第一个参数 param1 固定,其他两个参数在组合 val1 val2, val2 val3, val3 val4 中传递......等等,这相当于 (somefunction sampleparam1 val1 val2) (somefunction sampleparam1 val2 val3) (somefunction sampleparam1 val3 val4)...等。有没有办法在clojure中优雅地做到这一点?

我不确定你想对每次调用 somefunction 的结果做什么,所以我假设它是为了它的副作用而执行的,并使用 doseq.

(let [f (partial somefunction param1)]
  (doseq [args (partition 2 1 [val1 val2 val3 val4])]
    (apply f args)))

clojure.core/partition:

(partition 2 1 [1 2 3 4]) ;; ((1 2) (2 3) (3 4))

clojure.core/partial

(def plus10 (partial + 10))
(plus10 5) ;; 15

clojure.core/apply

(apply + [1 2 3]) ;; 6

注意:你可以不使用 partial 离开,因为 apply 接受中间参数:(apply somefunction param1 args)

我想我明白你问题的要点了。

;; a function that returns the vector as pairs of sub-vectors
(defn pairs [v]
  (map vector v (rest v)))

这会将您的向量 [val1 val2 val3...] 拆分为您想要的成对序列。

示例输出是

(pairs [1 2 3])
=> ([1 2] [2 3])

正如@Kyle 指出的那样,您也可以在这里使用 (partition 2 1 v),因为您真正感兴趣的只是序列,而不是实际的向量,因为它们稍后会通过 apply 压缩为参数。

接下来,您的函数需要做一些事情。为了在输出中进行说明,我只 return 一个将参数作为键值的映射 :a :b :c

(defn somefn [p1 p2 p3]
  {:a p1 :b p2 :c p3})

现在创建一个调用您的函数的新函数,但第一个参数为常量。我将只使用 :p1 作为标记。因此你只需要调用 (partial-somefn p2 p3) 就会调用 (somefn :p1 p2 p3)

(def partial-somefn (partial somefn :p1))

然后用你的向量(或序列)中的对调用它...

要么使用地图...

(map #(apply partial-somefn %) (pairs [1 2 3]))
=> ({:b 1, :c 2, :a :p1} {:b 2, :c 3, :a :p1})

或使用 doseq 治疗副作用...

(doseq [ps (pairs [1 2 3])]
  (apply partial-somefn ps))

或for循环

(for [ps (pairs [1 2 3])]
  (apply partial-somefn ps))
=> ({:b 1, :c 2, :a :p1} {:b 2, :c 3, :a :p1})

您可以看到映射 returned 显示参数是按顺序调用的,第一个参数是常量。

所以压缩版是

(defn somefn [p1 p2 p3]
  ;; your code here
  )

(def v [:v1 :v2 :v3])
(let [pairs (fn [v] (map vector v (rest v)))
      pf    (partial somefn :param1)]
  (map #(apply pf %) (pairs v)))

或根据 somefn 的作用使用 fordoseq 变体之一

维诺斯,有:

您首先要求创建一个最多接受三 (3) 个参数的函数:[param1 param2 param3] 但您希望能够修复第一个参数。此外,虽然您已经声明您有一个参数向量,但从您的文章来看,您想要遍历值向量,以便第一次调用 somefunction 从中获取第一项和第二项向量,第二次调用从向量中取出第 2 项和第 3 项,依此类推,直到向量耗尽。

你问题的第一部分(固定的第一个参数)可以通过以下方式解决:

(partial somefunction sampleparam1)

第二部分有点复杂,没有更多细节我只能猜测。但这里是一种方法的小演示:

(defn somefunction
  [param1 param2 param3]
  (+ param1 param2 param3))

(def part (partial somefunction 100))

(let [x [1 2 3 4 5]
      y (first x)
      z (second x)]
  (part y z))

如果你能详细解释一下

  1. 值向量的长度是否一致?
  2. somefunction 是做什么的?

我的第一个想法是使用 reduceloop,但我不愿假设太多。