Clojure-函数中参数的未知数量

Clojure-函数中参数的未知数量,clojure,Clojure,我有一个函数 (defn x [w] (let [[w1 w2 w3] w] (println w1) (println w2) (println w3))) 如果我调用函数 (x [[1 1] [2 2] [3 3]]) => [1 1] [2 2] [3 3] 这正是我所期望的 有没有办法概括这一点?在这种情况下,我知道w是一个包含3个向量的向量,因此我知道有[w1 w2 w3]如果w是一个包含4个向量的向量,那么最后一个向量将不会设置为任

我有一个函数

(defn x [w]
  (let [[w1 w2 w3] w]
    (println w1)
    (println w2)
    (println w3))) 
如果我调用函数

(x [[1 1] [2 2] [3 3]])
=> [1 1]
   [2 2]
   [3 3]
这正是我所期望的

有没有办法概括这一点?在这种情况下,我知道
w
是一个包含3个向量的向量,因此我知道有
[w1 w2 w3]
如果
w
是一个包含4个向量的向量,那么最后一个向量将不会设置为任何值

我想要的是,
w
是n个向量的向量,然后在函数的
中让
将它们设置为
[w1 w2 w3…wn]
?(注释不一定必须是w1、w2、…wn)

println只是用来调试的,所以对函数来说并不重要

(x [[1 1] [2 2] [3 3]])
=> [1 1]
   [2 2]
   [3 3]
任何帮助都将不胜感激

(defn x [ws]
  (dorun (map println ws)))
比如说,

(x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> nil
  • map
    依次将
    println
    应用于每个
    ws
    ,返回
    nil
    结果是一个按需序列(惰性地)
  • dorun
    需要整个序列,在运行时丢弃它, 返回
    nil

如果要查看序列,请将
dorun
替换为
doall

(defn x [ws]
  (doall (map println ws)))

=> (x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> (nil nil nil)

比前者更简洁的替代方法是

(defn x [ws]
  (doseq [w ws] (println w)))
。。。对后者来说是

(defn x [ws]
  (for [w ws] (println w)))
比如说,

(x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> nil
  • map
    依次将
    println
    应用于每个
    ws
    ,返回
    nil
    结果是一个按需序列(惰性地)
  • dorun
    需要整个序列,在运行时丢弃它, 返回
    nil

如果要查看序列,请将
dorun
替换为
doall

(defn x [ws]
  (doall (map println ws)))

=> (x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> (nil nil nil)

比前者更简洁的替代方法是

(defn x [ws]
  (doseq [w ws] (println w)))
。。。对后者来说是

(defn x [ws]
  (for [w ws] (println w)))

如果您不知道有多少,您将如何参考
w1
w2
等?听起来您应该处理传入序列,而不是对其进行分解。
map
reduce
transduce
filter
只是一些可用的集合处理函数,它们不需要与集合元素进行硬编码关联。你会越来越喜欢这些……如果你不知道有多少,你将如何参考
w1
w2
等?听起来您应该处理传入序列,而不是对其进行分解。
map
reduce
transduce
filter
只是一些可用的集合处理函数,它们不需要与集合元素进行硬编码关联。你会越来越喜欢这些……我知道你使用
println
只是为了说明,但如果有人认为
(doall(map println ws))
是一个通用的好主意,我想评论一下,不鼓励使用它。对于不关心结果的集合的副作用处理,现代clojure最佳实践是
run
(run!println coll)
(doall(map…
可能有80%的时间是错误的(不考虑REPL的使用)。同样,您的答案仅使用
println
作为示例,因此这不是对您答案本身的评论,只是供阅读的任何人参考。对您的答案进行了投票。@Josh谢谢,Josh。我不知道
run!
。至于
println
,我只是按照OP所做的操作。我笨拙的代码是梳理出顺序进程Ing(我怀疑问题的真正要点)是副作用问题。我知道您使用的
println
仅用于说明目的,但以防任何阅读者认为
(doall(map println ws))
对于一般用途来说是一个好主意,我想评论一下以阻止它的使用。对于不关心结果的集合的副作用处理,现代clojure的最佳实践是
run!
(run!println coll)
(doall(map…
可能80%的时间是错误的(打消REPL的使用)。同样,您的答案仅使用
println
作为示例,因此这不是对您答案本身的评论,只是供阅读的任何人参考。对您的答案进行了投票。@Josh谢谢,Josh。我不知道
run!
。至于
println
,我只是按照OP所做的操作。我笨拙的代码是梳理出顺序进程Ing(我怀疑问题的真正意义)来自副作用问题。