Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to search through a plist repeatedly?

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

like image 939
schmoopy Avatar asked May 06 '11 07:05

schmoopy


2 Answers

Just list the keywords:

(loop for x in (list :a :b)
      collect (get-plist-value x))
like image 37
Svante Avatar answered Nov 15 '22 09:11

Svante


(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")))
like image 79
Matthias Benkard Avatar answered Nov 15 '22 09:11

Matthias Benkard