我最近在Lisp做了一个小项目来练习。它是一个简单的数据库创建者/管理者,到目前为止,它运作良好!我只有一个问题:当我以[人类可读]格式转储数据库的属性列表时,我只能打印这些值。我还需要打印属性名称,并且使用我当前的函数,我不能。
这是我到目前为止的代码(从内存写入,不是复制/粘贴):
(defun dump-list (list-to-dump &optional prefix)
(if (not (boundp prefix)) (setq prefix "") ;If it's nil, bind it to ""
(if (not (stringp prefix)) ;If they specified anything other than a string
(format "~a~%" "argument:prefix must be a string!")) ;then yell at them.
(dolist (item list-to-dump) ;Iterate through the items in the list
(if (listp item) ;If the item itself is a list (nested lists)
(dump-list item (concatenate 'string prefix " "));then dump that too, indented
(format t "~a~%" item)));Here's where I need help. I can't figure out how to
;output the value and its label at the same time.
它工作得很好,但只打印存储的值,而不是属性的名称。我正在寻找像这样的格式:
LABEL1: VALUE1
LABEL2: VALUE2
LABEL3:
NESTEDLABEL1: NESTEDVAL1
NESTEDLABEL2: NESTEDVAL2
NESTEDLABEL3:
TOOMANYLAYERS:YEP.
SORRY: ABOUT THAT.
创建如下列表:
(list :LABEL1 "VALUE1" :LABEL2 "VALUE2" :LABEL3
(list :NESTEDLABEL1 "NESTEDVALUE1" :NESTEDLABEL2 "NESTEDVALUE2" :NESTEDVALUE3
(list :TOOMANYLAYERS "YEP." :SORRY "ABOUT THAT.")))
很抱歉这里的语法不正确,我绝不是Lisp的专家。
prefix
是这样的,如果你想要缩进,它就会发生。它主要用于打印子列表比其父列表多两个空格。
我会尽力保持最新状态,但我在学校,所以大概六个小时后才能检查这个,就在我回家的时候。
答案 0 :(得分:3)
您忘记将第一个参数(result-type
)传递给concatenate
。
您忘记将第一个参数(destination
)传递给format
。
您的默认参数处理可以简化。
请避免晃来晃去,否则会违反公认的风格。
要回答您的实际问题:请使用loop
这是我的代码:
(defun dump-list (list-to-dump &optional (prefix ""))
(unless (stringp prefix) ; or (check-type prefix string) instead of the whole unless form
(setq prefix (princ-to-string prefix))) ; or (coerce prefix 'string) instead of princ
(fresh-line) ; start with a new line if something has already been printed
(loop :for (label item) :on list-to-dump :by #'cddr :do
(format t "~a~a:" prefix label)
(if (consp item) ; treat NIL as a single value, not a list
(dump-list item (concatenate 'string prefix " "))
(format t " ~a~%" item))))
它打印出你想要的东西:
LABEL1: VALUE1
LABEL2: VALUE2
LABEL3:
NESTEDLABEL1: NESTEDVALUE1
NESTEDLABEL2: NESTEDVALUE2
NESTEDVALUE3:
TOOMANYLAYERS: YEP.
SORRY: ABOUT THAT.
如果您坚持要检查prefix
的类型(而不是将其转换为字符串),请使用代码中指示的check-type
。