如何修改此功能以创建动态plist

问题描述

要做什么:我想定义一个函数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

和一个plist (property list)

(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)