如何从plist获取属性 [英] How to get a property from a plist
问题描述
我是Lisp的新手. 我想使用这样的字符串变量从属性列表中访问特定属性
I am a newbie in Lisp. I want to access a particular property from a property list with a string variable like this
(setf sym (list :p1 1))
(setf x "p1")
(getf sym :x)
推荐答案
关于cl:getf
让Petit Prince的答案正确是 getf 可能是您要在此处使用的功能,但是请注意,它不仅可以用于关键字符号,还可以用于更多功能.您可以将其用于任何对象.属性列表只是交替显示指标和值的列表,任何对象都可以是指标:
About cl:getf
Let Petit Prince's answer is right that getf is probably the function you want to use here, but note that it can be used for more than just keyword symbols. You can use it for any objects. A property list is just a list of alternating indicators and values, and any object can be an indicator:
(let ((plist (list 'a 'b 'c 'd)))
(getf plist 'c))
;=> D
您甚至可以使用字符串作为指示符:
You can even use strings as indicators:
(let* ((name "p1")
(plist (list name 1)))
(getf plist name))
;=> 1
但是,这不是一个好习惯,因为 getf 将指标与 eq 进行比较.这意味着使用字符串作为指示符可能并不可靠,具体取决于您的用例:
However, that's probably not great practice, since getf compares indicators with eq. That means that using strings as indicators might not be reliable, depending on your use case:
(let ((plist (list "p1" 1)))
(getf plist "p1"))
;=> NIL
以您为例
在您的情况下,您尝试获取一个字符串并找到名称与字符串相等(即,具有相同字符,但不考虑大小写)的符号的对象.在列表中循环并将指标与字符串相等进行比较可能更有意义.
For your example
In your case, you're trying to take a string and find the object for a symbol with a name that's string-equal (i.e., with the same characters, but disregarding case). It probably makes more sense to loop over the list and compare indicators with string-equal.
(let ((plist '(:p1 1 :p2 2)))
(loop
for (indicator value) on plist by #'cddr
when (string-equal indicator "p1")
return value))
;=> 1
当然,您可以将其包装在一个抽象函数中:
And of course, you can wrap that up in a function for abstraction:
(defun getf-string-equal (plist indicator)
(loop
for (i v) on plist by #'cddr
when (string-equal i indicator)
return v))
(getf-string-equal '(:p1 1 :p2 2) "p1")
;=> 1
这篇关于如何从plist获取属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!