如何在 clojure 中转置嵌套向量

Dan*_* Wu 3 clojure

我有以下变量

 (def a [[1 2] [3 4] [5 6]])
Run Code Online (Sandbox Code Playgroud)

并想返回

[[1 3 5][2 4 6]]
Run Code Online (Sandbox Code Playgroud)

如果输入是 [[1 2] [3 4] [5 6] [7 8 9]]那么所需的结果是

[[1 3 5 7] [2 4 6 8] [9]]
Run Code Online (Sandbox Code Playgroud)

如何在 Clojure 中做到这一点?

ife*_*ett 5

(persistent!
  (reduce
   (fn [acc e]
     (reduce-kv
      (fn [acc2 i2 e2]
        (assoc! acc2 i2 ((fnil conj []) (get acc2 i2) e2)))
      acc
      e))
   (transient [])
   [[1 2 3] [:a :b] [\a] [111] [200 300 400 500]]))

;;=> [[1 :a \a 111 200] [2 :b 300] [3 400] [500]]
Run Code Online (Sandbox Code Playgroud)

空向量可以通过第 0 个索引处的 update-in fn 进行更新,此外,可以在紧随最后一个值之后的索引处更新非空向量。

这里的归约是将外部累加器传递给内部归约函数,相应地更新它,然后将其返回到外部归约函数,而外部归约函数又将再次传递到内部 rf 来处理下一个元素。

编辑:更新到最快的版本。