一个相当简单的程序,为了练习/学习,我尝试用Common编写它。我相信这可以做得更优雅,但Lisp的字符串处理似乎非常困难。
(defun d20 () (+ 1 (random 19)))
(defun initlist (specs)
(let* ((ilist (map 'list #'(lambda (n) `(,(first n) ,(+ (second n) (d20)))) specs))
(sortedilist (sort ilist #'> :key #'second)))
sortedilist))
(defun htmlinitlist (specs)
(apply #'uiop:strcat `("<table><tr><td> </td><td> </td></tr>"
,@(loop for (a b) in (initlist specs) collecting
(format nil "<tr><td>~A</td><td>~A</td></tr><tr><td> </td><td> </td></tr>"
a b))
"</table>")))
(defun htmlinitlists (specs count)
(format nil "~{ ~A~}" (loop for i from 0 to count collecting (htmlinitlist specs))))来自REPL的示例用法:
(htmlinitlists '(("Elvish" 5) ("Wizgit" 2) ("Alaric" 8) ("Pounder" 6)) 17)发布于 2019-08-27 07:38:39
如果愿意,我会将流转换为字符串。
(defun d20 () (+ 1 (random 19)))initlist可以编写得更紧凑:
(defun initlist (specs)
(sort (loop for (a b) in specs collect (list a (+ b (d20))))
#'> :key #'second))现在,我们将流传递给htmlinitlist,并将内容写入流:
(defun htmlinitlist (specs stream)
(write-string "<table><tr><td> </td><td> </td></tr>" stream)
(loop for (a b) in (initlist specs) do
(format stream
"<tr><td>~A</td><td>~A</td></tr><tr><td> </td><td> </td></tr>"
a b))
(write-string "</table>" stream))如果我们想从流中获取字符串,我们可以使用with-output-to-string。这就绑定了一个流变量,我们可以使用它来传递.
(defun htmlinitlists (specs count)
(with-output-to-string (stream)
(write-char #\space stream)
(loop repeat (1+ count) do (htmlinitlist specs stream))))只使用一个htmlinitlist调用的替代FORMAT版本:
(defun htmlinitlist (specs stream)
(format stream
"<table><tr><td> </td><td> </td></tr>~
~{<tr><td>~A</td><td>~A</td></tr><tr><td> </td><td> </td></tr>~}~
</table>"
(loop for (a b) in (initlist specs) collect a collect b)))所有各种字符串操作(正在创建大量中间字符串,立即成为垃圾)已被替换为通常的输出函数和流。
https://codereview.stackexchange.com/questions/225832
复制相似问题