Clojure列表理解-在特定情况下只运行一次内部循环?
有没有一种方法可以使用单一列表comp来实现以下目标,或者我需要其他方法Clojure列表理解-在特定情况下只运行一次内部循环?,clojure,Clojure,有没有一种方法可以使用单一列表comp来实现以下目标,或者我需要其他方法 (def args'([:db/foo 12][:db/bar 34]{:a1:b2})) (定义myfunc[] “如果arg是映射,则只希望运行一次内部循环。” (对于[arg args[cmd¶ms]arg];“cmd¶ms”在映射时没有意义。 (如果(映射参数) arg (输入[cmd]参数))) 以上代码生成 => [[:db/foo 1 2] [:db/bar 3 4] {:a 1, :
(def args'([:db/foo 12][:db/bar 34]{:a1:b2}))
(定义myfunc[]
“如果arg是映射,则只希望运行一次内部循环。”
(对于[arg args[cmd¶ms]arg];“cmd¶ms”在映射时没有意义。
(如果(映射参数)
arg
(输入[cmd]参数)))
以上代码生成
=> [[:db/foo 1 2] [:db/bar 3 4] {:a 1, :b 2} {:a 1, :b 2}]
但我真的想要
=>[[:db/foo 12][:db/bar 34]{:a1,:b2}]
显然,这不是完整的函数,如果arg是向量形式,但希望让map形式直接通过(而不被复制),我将进行变换
更新:我发现a有其根源,而“有条件地执行内部循环”实际上是一个必须的概念,因此这并不奇怪一个单一的列表理解不容易表达,这完全是fp构造。这就是你想要做的吗?: 从现有序列构建新序列。对于输入序列中的每个元素,有两种可能的情况:
- 这是一个映射:在这种情况下,只需将其附加到结果序列
- 否则它是一个序列,它的元素可能应该被转换并附加到结果序列中
mapcat
将映射与连接相结合,可以通过直接将序列传递给mapcat
(mapcat (fn [x] (if (map? x) [x] x)) args)
或者使用mapcat
作为传感器
(into [] (mapcat (fn [x] (if (map? x) [x] x))) args)
我认为
for
不适合表示此计算。在我提出解决方案之前,我对您提供的函数myfunc
有几点意见:
- 文档字符串放错了位置。我知道这很奇怪,但是doc字符串必须在函数的参数之前,所以在
之前[]
- 我认为,您对指令使用的
不是您所期望的。您应该看看中的示例。主要是
指令很适合从列表构造笛卡尔积for
循环
指令构建一个向量,该向量将包含每个参数:
(defn myfunc“如果arg是映射,则只希望运行一次内部循环。”
[&args]
(循环[arg以解析args
res[]]
(如果(空?要分析的参数)
物件
(let[arg(要分析的第一个arg)
要分析的新参数(要分析的rest参数)]
(如果(映射参数)
(重现要分析的新参数(conj res arg))
(重现要分析的新参数(转换为res参数))
)))))
(myfunc[:db/foo 12][:db/bar 34]{:a1:b2})
;; => [[:db/foo 12][:db/bar 34]{:a1,:b2}]
(myfunc{:a1:b2}[:db/foo2][:db/bar 34]]
;; => [{:a1,:b2}[:db/foo 12][:db/bar 34]]
(mapcat(fn[x](if(map?x)[x]x)))
因为传感器似乎也这样做(至少对于给定的测试用例)@cfrick我完全忘记了mapcat
。这是一个很大的改进,东西变得简洁多了!