通过一系列函数和一个seq中的其他参数对数据结构进行线程处理
问题描述:
这是对我之前的问题here的扩展。通过一系列函数和一个seq中的其他参数对数据结构进行线程处理
目的被示为如下:
(defn foo
[x a-map]
(assoc a-map x "value"))
(defn -main
[x]
(let [[x1 x2 x3 ... xn] x]
(-> {}
(partial foo x1)
(partial foo x2)
(partial foo x3)
...
(partial foo xn))))
的这个问题的复杂性在于,我必须填充可变数量的部分功能,所以我不能使用->
也不“排版”。 foo
函数的真正机制当然不是assoc
,所以我不能简化为zipmap
的问题。
我不确定这个问题,但输入参数x
实际上是两个序列的笛卡尔乘积。因此,x
的每个元素都是一个两元素向量,它遍历两个序列的笛卡尔乘积空间。它使用for
循环生成,或者更确切地说是列表理解。
你有什么建议来处理这个问题?如果我没有提供一些重要信息,请告诉我。
干杯
答
首先,你的thread first ->
macro使用不正确(参见this question获取更多信息)。下面是使用thread last ->>
macro正确的语法:
(->> {}
(foo x1)
(foo x2)
(foo x3)
(foo x4))
虽然,它不会工作,除非矢量x
的长度是威慑。
但是你可以使用reduce
function这里来处理元素的任意序列:
(reduce #(assoc %1 %2 "value") {} x)
下面是一个完整的例子(与重新定义了foo
功能):
(defn foo
[a-map x] ; reversed order of arguments
(assoc a-map x "value"))
(defn -main
[x]
(reduce foo {} x))
美丽!关于我的双重循环嵌套方式,在真正的数据操作习惯之前是否构建了一个笛卡尔seq?或者有什么其他的选择来做到这一点? – Davyzhu 2015-03-25 08:24:42
在将它提供给'reduce'之前,用'for'循环构建一个笛卡尔积是一个很好的解决方案,因为'for'产生一个懒惰的序列。但请确保不要持有产生懒惰序列的头。 – 2015-03-25 08:30:49
但你为什么提到嵌套'for'循环?在Clojure中,只需一个'for'循环即可生成笛卡尔产品。 – 2015-03-25 08:31:44