我如何修改此功能以创建动态 plist
how can I modify this function to create a dynamic plist
我想做什么:我想定义一个函数create-record
,它接受可变数量的参数(称为键的名称)并生成一个动态plist/named列表。
我只是想让它首先使用动态名称并将 1 分配给所有名称以创建一个列表,如 (:x 0 :y 0 :z 0)
然后我可以修改它以接受键和值(而不是仅仅0 代表所有关键)
我的代码:
(defparameter *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)
。
问题不在于函数,而在于调用。
你需要做的是
(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)
如果要将列表作为参数传递,只需删除 &rest
。
回答评论中的问题,这里是如何创建alist
(协会列表):
(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-plist (keys values)
(mapcan #'list keys values))
(defparameter *my-plist* (make-plist '(:a :b :c) '(1 2 3)))
(getf *my-plist* :b)
==> 2
(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)
我想做什么:我想定义一个函数create-record
,它接受可变数量的参数(称为键的名称)并生成一个动态plist/named列表。
我只是想让它首先使用动态名称并将 1 分配给所有名称以创建一个列表,如 (:x 0 :y 0 :z 0)
然后我可以修改它以接受键和值(而不是仅仅0 代表所有关键)
我的代码:
(defparameter *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)
。
问题不在于函数,而在于调用。 你需要做的是
(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)
如果要将列表作为参数传递,只需删除 &rest
。
回答评论中的问题,这里是如何创建alist (协会列表):
(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-plist (keys values)
(mapcan #'list keys values))
(defparameter *my-plist* (make-plist '(:a :b :c) '(1 2 3)))
(getf *my-plist* :b)
==> 2
(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)