Clojure:希望懒惰地将任意列表转换为字符串表示形式



我厌倦了根据列表的结构编写列表结构的大量代码。例如,对于

'(1 2 3),我

(apply str '(1 2 3))但对于

'((1 2 3) (4 5 )),我应该

(map #(apply str %) '((1 2 3) (4 5 )))

等,取决于列表的嵌套结构。

我想知道处理任意列表结构的优雅功能是什么?

下面是一个草图,希望学习更好的解决方案。

(defun to-string
"convert argument into string."
([x & xs] (str (to-string x) (to-string xs) "n"))
([x] (str x))
)

预先感谢!

如果要获得一些一致但完全控制的方法来格式化任何数据,则可以从clojure.pprint使用cl-format函数。它是Common LISP出色format功能的端口。例如,例如:

user> (require '[clojure.pprint :refer [cl-format]])
nil
user> (cl-format nil "~{~a~}" '(1 2 3 4))
"1234"
user> (cl-format nil "~{~{~a~}~^ ~}" '((1 2) (3 4) (5 6)))
"12 34 56"

等等。这里有一个不错的教程:http://www.gigamonkeys.com/book/a-few-format-recipes.html,以及clhs

中的更多信息

例如,您可以走得更远,并制作一些格式生成函数(或宏):

user> (defmacro make-fstring [level]
        (nth (iterate #(str "~{" % "~^ ~}") "~{~a~}") (dec level)))
#'user/make-fstring
user> (cl-format nil (make-fstring 2) '((1 2 3) (4 5 6)))
"123 456"
user> (cl-format nil (make-fstring 3) '(((1 2) (3 4) (5 6) (7 8)) 
                                        ((9 10) (11 12))))
"12 34 56 78 910 1112"

pprint将打印出良好格式的数据结构:

user=> (clojure.pprint/pprint '('(1 2 3) '(4 5 )))
('(1 2 3) '(4 5))

您可以使用with-out-str绑定*out*pprint的输出发送到字符串而不是stdout

(def s 
  (with-out-str 
     (clojure.pprint/pprint '('(1 2 3) '(4 5 )))))

最新更新