我是Clojure和函数式编程的新手.我对如何以功能方式处理这个问题感到茫然.
我有以下矩阵:
(def matrix [[\a \b \c]
[\d \e \f]
[\g \h \i]])
Run Code Online (Sandbox Code Playgroud)
我想把它变成这样的东西(逆时针旋转):
((\a \d \g)
(\b \e \h)
(\c \f \i ))
Run Code Online (Sandbox Code Playgroud)
我已经破解了这一点,它以正确的顺序给了我元素.如果我能以这种方式收集字符串中的数据,那么我可以将其与分区分开.但是我很确定doseq是错误的路径:
(doseq [i [0 1 2]]
(doseq [row matrix]
(println (get (vec row) i))))
Run Code Online (Sandbox Code Playgroud)
我已经涉足了嵌套的地图调用,但仍然坚持使用它.在Clojure中构建字符串或以更好的方式处理这个字符串的正确方法是什么?
Jan*_*Jan 32
你想要达到的目的听起来像转置.我建议
(apply map list matrix)
; => ((\a \d \g) (\b \e \h) (\c \f \i))
Run Code Online (Sandbox Code Playgroud)
它有什么作用?
(apply map list '((\a \b \c) (\d \e \f) (\g \h \i)))
Run Code Online (Sandbox Code Playgroud)
相当于
(map list '(\a \b \c) '(\d \e \f) '(\g \h \i))
Run Code Online (Sandbox Code Playgroud)
它接受三个列表中每个列表的第一个元素,对它们调用列表,然后接受第二个元素,对它们调用列表......返回以这种方式生成的所有列表的序列.
在ClojureDocs 上可以找到更多关于apply和map的例子.
取矩阵转置直接从rosettacode溶液:
(vec (apply map vector matrix))
要了解正在发生的事情,请考虑:
(map vector [\a \b \c] [\d \e \f] [\g \h \i])Run Code Online (Sandbox Code Playgroud)
这对于任意矩阵维度都可以很好地工作,尽管它对于大数字运算并不好,因为您可以考虑使用来自Clojure的基于Java的矩阵操作库.
您可以core.matrix非常轻松地使用这些矩阵操作.特别是,已经有一个transpose功能完全符合您的要求:
例:
(use 'clojure.core.matrix)
(def matrix [[\a \b \c]
[\d \e \f]
[\g \h \i]])
(transpose matrix)
=> [[\a \d \g]
[\b \e \h]
[\c \f \i]]
Run Code Online (Sandbox Code Playgroud)