需要你的帮助。坚持一个直观简单的任务。
我有一些载体向量。每个子向量的第一个元素是数字键。所有父矢量都按这些键排序。例如:
[[1 a b] [3 c d] [4 f d] .... ]
[[1 aa bb] [2 cc dd] [3 ww qq] [5 f]... ]
[[3 ccc ddd] [4 fff ddd] ...]
需要澄清嵌套向量中的某些键值可能会丢失,但保证排序顺序。
我需要通过数字键将所有这些向量合并到一个统一的结构中。我现在还需要在原始矢量或矢量中遗漏一把钥匙。
像这样:
[ [[1 a b][1 aa bb][]] [[][2 cc dd]] [[3 c d][3 ww qq][3 ccc ddd]] [[4 f d][][4 fff dd]]...]
答案 0 :(得分:2)
我没有完整的解决方案,但作为提示:使用group-by
为第一个参数排序向量。
这将更加惯用,并且在准备就绪时可能只有几行。
所以你可以写点像
(group-by first [[1 :a :b] [3 :c :d] [4 :f :d]])
并为所有向量执行此操作。然后,您可以使用group-by
提供的密钥对它们进行排序/合并。
答案 1 :(得分:2)
您可以将问题分解为两部分:
1)按排序顺序获取唯一键
2)对于每个唯一键,迭代向量列表,并输出键的条目,如果缺少则输出空列表
要获取唯一键,只需将所有键拉出到列表中,将它们连接成一个大列表,然后将它们放入一个排序集:
(into
(sorted-set)
(apply concat
(for [vector vectors]
(map first vector))))
如果我们从矢量列表开始:
(def vectors
[[[1 'a 'b] [3 'c 'd] [4 'f 'd]]
[[1 'aa 'bb] [2 'cc 'dd] [3 'ww 'qq] [5 'f]]
[[3 'ccc 'ddd] [4 'fff 'ddd]]])
然后我们得到一组有序的:
=> #{1 2 3 4 5}
到目前为止一切顺利。现在,对于该有序集合中的每个键,我们需要迭代向量,并使用该键获取条目,如果缺少则获取空列表。您可以使用两个'for'表单然后'some'来查找条目(如果存在)
(for [k #{1 2 3 4 5}]
(for [vector vectors]
(or (some #(when (= (first %) k) %) vector )
[])))
这会产生:
=> (([1 a b] [1 aa bb] []) ([] [2 cc dd] []) ([3 c d] [3 ww qq] [3 ccc ddd]) ([4 f d] [] [4 fff ddd]) ([] [5 f] []))
我认为这就是你想要的。 (如果你需要向量而不是列表,只需在适当的位置使用“(进入[] ...)”。)
总而言之,我们得到:
(defn unify-vectors [vectors]
(for [k (into (sorted-set)
(apply concat
(for [vector vectors]
(map first vector))))]
(for [vector vectors]
(or (some #(when (= (first %) k) %) vector)
[]))))
(unify-vectors
[[[1 'a 'b] [3 'c 'd] [4 'f 'd]]
[[1 'aa 'bb] [2 'cc 'dd] [3 'ww 'qq] [5 'f]]
[[3 'ccc 'ddd] [4 'fff 'ddd]]])
=> (([1 a b] [1 aa bb] []) ([] [2 cc dd] []) ([3 c d] [3 ww qq] [3 ccc ddd]) ([4 f d] [] [4 fff ddd]) ([] [5 f] []))
答案 2 :(得分:1)
这是一个简单的解决方法,但不符合Clojure编程的最佳实践。只是在这里给出一个简单的想法。
(def vectors
[
[[1 'a 'b] [3 'c 'd] [4 'f 'd]]
[[1 'aa 'bb] [2 'cc 'dd] [3 'ww 'qq] [5 'f]]
[[3 'ccc 'ddd] [4 'fff 'ddd]]]
)
(loop [i 1
result []]
(def sub-result [])
(doseq [v vectors]
(doseq [sub-v v]
(if
(= i (first sub-v))
(def sub-result (into sub-result [sub-v]))))
(if-not
(some #{i}
(map first v))
(def sub-result (into sub-result [[]]))
))
(if (< i 6)
(recur (inc i) (into result [sub-result]))
(print result)))