I am trying to learn LISP and I'm getting hung up on something basic -
I want to loop through a list and lookup a plist value from the list value...
; here it just looks up the plist value
(defun get-plist-value(x) (getf (list :a "1" :b "2") x))
; this is what i want to do, but it doesnt work
; i have tried concatenating the ":" before the x value, but it didnt work either
(loop for x in '(a b) do (get-plist-value x))
; this works
(get-plist-value :a)
thank you :-)
Just list the keywords:
(loop for x in (list :a :b)
collect (get-plist-value x))
(loop for x in '(a b) do (get-plist-value x))
There are two issues here.
First, the symbol a
is not the same as the symbol :a
(unless you're in the keyword
package, which is very unlikely), so it will fail to find anything. Likewise for b
.
Second, this will look up a value, return it from the get-plist-value
call, and then discard it without doing anything with it. If you want to collect all found items into a new list and have the loop return that list, use collect
rather than do
; if you want to output the found items, use something like do (format t "~&~A" (get-plist-value x))
; and so on.
Addendum: Note that the colon in the printed representation of :a
is an artifact of how symbols are printed. The colon is a package prefix which signifies that the symbol is in the keyword
package. It's not a part of the symbol's name, so simply concatenating symbol names isn't going to help. If you want get-plist-value
to compare symbols by name only, you can do something like the following, although it's probably not the prettiest possible solution:
(defun get-plist-value (x)
(getf (list :a "1" :b "2")
(intern (symbol-name x) "KEYWORD")))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With