使用向量中的参数应用具有多个参数的函数
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)))
(partition 2 1 [1 2 3 4]) ;; ((1 2) (2 3) (3 4))
(def plus10 (partial + 10))
(plus10 5) ;; 15
(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 的作用使用 for
或 doseq
变体之一
维诺斯,有:
您首先要求创建一个最多接受三 (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))
如果你能详细解释一下
- 值向量的长度是否一致?
somefunction
是做什么的?
我的第一个想法是使用 reduce
或 loop
,但我不愿假设太多。
我有一个函数,它接受三个参数 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)))
(partition 2 1 [1 2 3 4]) ;; ((1 2) (2 3) (3 4))
(def plus10 (partial + 10))
(plus10 5) ;; 15
(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 的作用使用 for
或 doseq
变体之一
维诺斯,有:
您首先要求创建一个最多接受三 (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))
如果你能详细解释一下
- 值向量的长度是否一致?
somefunction
是做什么的?
我的第一个想法是使用 reduce
或 loop
,但我不愿假设太多。