问题描述
我要做什么:我想定义一个函数create-record
,该函数接受可变数量的参数(称为键的名称)并生成动态plist /命名列表。
我只是想首先让它与动态名称一起使用,并为所有名称分配1来创建一个像(:x 0 :y 0 :z 0)
这样的列表,然后我可以对其进行修改以接受键和值(而不是仅接受0一切关键)
我的代码:
(defp@R_404_6460@meter *test* '('x 'y 'z))
(defun create-record (&rest keys)
(let ((count 0))
(mapcan (lambda (key) (list key count)) keys)))
(create-record-variable *test*)
==> (('X 'Y 'Z) 0)
预期输出:
(create-record-variable *test*)
==> (:x 0 :y 0 :z 0)
我不确定输出为什么像(('X 'Y 'Z) 0)
。
解决方法
问题不在于功能,而在于调用。 您需要做的是
name mpg disp hp drat wt qsec vs am gear carb
1 Mazda 22.8 108 93 3.85 2.32 18.61 1 1 4 1
2 Honda 21.0 160 110 3.90 2.62 16.46 0 1 4 4
3 Suzuki 18.7 360 175 3.15 3.44 17.02 0 0 3 2
或者,如果关键字在列表中,
(create-record 'a :b '#:c)
==> (A 0 :B 0 #:C 0)
如果要将列表作为参数传递,则只需删除(defparameter *test* '(:x :y :z))
(apply #'create-record *test*)
==> (:X 0 :Y 0 :Z 0)
。
回答评论中的问题,以下是如何创建alist (association list):
&rest
(defun make-alist (keys values)
(mapcar #'cons keys values))
(defparameter *my-alist* (make-alist '(:a :b :c) '(1 2 3)))
(assoc :a *my-alist*)
==> (:A . 1)
,
(defun make-keyword (x)
"Make out of symbol or string a keyword."
(values (intern (string x) "KEYWORD")))
;; this is equivalent to alexandria's `alexandria::make-keyword
;; (defun make-keyword (x)
;; (read-from-string (concatenate 'string ":" (string x))))
;; ;; this doesn't work with "such strings"
(defun create-record (list-of-symbols &key (count 0))
(mapcan #'(lambda (x) (list (make-keyword x) count)) list-of-symbols))
然后称呼它:
(defparameter *test* (list 'x 'y 'z))
(create-record *test*)
;; => (:X 0 :Y 0 :Z 0)
(create-record *test* :count 3)
;; => (:X 3 :Y 3 :Z 3)