zwr has quit [Read error: Connection reset by peer]
decweb has quit [Quit: Konversation terminated!]
zwr has joined #commonlisp
triffid has quit [Remote host closed the connection]
triffid has joined #commonlisp
admich1 has quit [Ping timeout: 252 seconds]
admich1 has joined #commonlisp
_whitelogger has joined #commonlisp
adrianbrink has quit [Ping timeout: 265 seconds]
adrianbrink has joined #commonlisp
mustafa has quit [Ping timeout: 248 seconds]
sujeet` has joined #commonlisp
nxtr has quit [Ping timeout: 276 seconds]
sujeet has quit [Ping timeout: 248 seconds]
alfiee has quit [Ping timeout: 272 seconds]
etimmons has quit [Ping timeout: 276 seconds]
etimmons has joined #commonlisp
nxtr has joined #commonlisp
mustafa has joined #commonlisp
alfiee has joined #commonlisp
edgar-rft has joined #commonlisp
edgar-rft` has quit [Ping timeout: 260 seconds]
istewart has quit [Quit: Konversation terminated!]
pve has joined #commonlisp
ewig has joined #commonlisp
chomwitt has joined #commonlisp
rgherdt has joined #commonlisp
admich1 has quit [Ping timeout: 260 seconds]
admich1 has joined #commonlisp
Guest47 has joined #commonlisp
lcn_ has joined #commonlisp
RDMengineer1 has joined #commonlisp
RDMengineer has quit [Ping timeout: 245 seconds]
RDMengineer1 is now known as RDMengineer
aeth_ has joined #commonlisp
aeth has quit [Quit: ...]
aeth has joined #commonlisp
mgl has joined #commonlisp
aeth_ has quit [Quit: ...]
bpanthi979 has joined #commonlisp
bpanthi979 is now known as bpanthi978
bpanthi977 has quit [Ping timeout: 260 seconds]
bpanthi978 is now known as bpanthi977
bpanthi978 has joined #commonlisp
mgl has quit []
bpanthi977 has quit [Ping timeout: 252 seconds]
bpanthi978 is now known as bpanthi977
mwnaylor has joined #commonlisp
<phil_bb>
Hey folks silly question, I can't seem to find any function like (member) that will work with plists, and trying to (loop :for (key val) :in *plist*...) throws an error of ":NAME is not of type LIST" (:NAME is the first property).
<phil_bb>
A little bit at a loss how I can simply check if a value exists in the list.
<phil_bb>
Structurally, I have a simple list that contains 180+ plists with about 15 properties each.
<beach>
Try using ON instead of IN, and use BY #'CDDR to get even elements only.
<beach>
You are trying to match the list (KEY VAL) to the symbol :NAME.
<beach>
Hence the error.
<beach>
But there are also functions for property lists.
<phil_bb>
I haven't been able to find any functions, thus the question.
<gilberth>
If your task is to check for the presence of a key in a plist try something like: ,(let ((notthere (list nil))) (defun has-key-p (plist key) (not (eq (getf plist key notthere) notthere)))) ,(has-key-p '(:foo nil) :foo) ,(has-key-p '(:foo nil) :bar)
<beach>
phil_bb: Is that ^ something like what you want?
<phil_bb>
Ok, so I need to be able to retrieve 1. the complete plist where the property-value pair is. 2. the value of the property of the correct plist. 3. A list of plists which contain matching properties.
<phil_bb>
For example, I should be able to retrieve all plists whose :region is "Europe", and then from these get the names of the countries.
<phil_bb>
The problem is that running (equals (getf prop plist) query) doesn't seem to return anything when called from a loop statement.
<beach>
phil_bb: Check the argument order for GETF.
<phil_bb>
Sorry, you're correct, I mistyped.
<gilberth>
How about (defun filter-by-key-value (key wanted-value) (remove-if-not (lambda (plist) (equal (getf plist key) wanted-value)) plists)) ?
<phil_bb>
But then I need to specify the key, which I'm trying to avoid as it limits matches. That's why I was trying to use (member)
<gilberth>
I still don't get what exactly you want. MEMBER checks for the presence of a value in a list by returning the sublist that starts with that value. What is the analogue with plists that you want?
<phil_bb>
This is the part that would solve all my issues:
<phil_bb>
(defun iso-cc-search (query)
<phil_bb>
(loop :for c :in *iso-country-codes*
<phil_bb>
:for (key val) :on c :by #'cddr
<phil_bb>
:when (equal val query)
<phil_bb>
:collect c))
<beach>
Please use a paste site for more than one line of code.
<gilberth>
So you want a list of all keys that have some specific value?
<phil_bb>
All the plists (*iso-country-codes* is a plain list of plists) that contain a matching value.
<phil_bb>
beach: I'll keep that in mind, I didn't think it was a big deal since it's only a few lines.
<phil_bb>
The issue I'm running into is that this returns nil, even though I know for a fact that "AF" exists (Afghanistan, first plist in the *iso-country-codes* list.)
<gilberth>
*ISO-COUNTRY-CODES* is a list of plist?
<beach>
I suspect you need a nested loop.
<phil_bb>
Correct. Let me pastebin these real quick.
treflip has joined #commonlisp
<gilberth>
It puzzles me that you don't care which key has that value QUERY.
<beach>
Something like (loop for c in *iso-country-codes* append (loop for (key val) on c by #'cddr ...))
King_julian has quit [Ping timeout: 245 seconds]
<phil_bb>
It's because some countries use different codes for different keys. Especially the smaller countries have differences, e.g. the Aland Islands use 'AX' for their alpha-2 country code
<phil_bb>
But then Albania uses Al
<beach>
phil_bb: I suspect you need a nested loop.
King_julian has joined #commonlisp
<phil_bb>
Isn't that what the two :for clauses do? I was sure that if I don't use :and, they'll act as nested.
<gilberth>
No, they would run in parallel not nested.
<phil_bb>
The documentation said that they'll run in parallel *with* :and, that's why I avoided it. I'll need to go and read more into this.
<beach>
phil_bb: Try the template I gave above.
<gilberth>
phil_bb: Compare ,(LOOP FOR I BELOW 3 FOR J BELOW 3 COLLECT (LIST I J)) to ,(LOOP FOR I BELOW 3 APPEND (LOOP FOR J BELOW 3 COLLECT (LIST I J)))
<ixelp>
(LOOP FOR I BELOW 3 FOR J BELOW 3 COLLECT (LIST I J)) => ((0 0) (1 1) (2 2)), further (LOOP FOR I BELOW 3 APPEND (LOOP FOR J BELOW 3 COLLECT (LIST I J))) => ((0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2))
<gilberth>
Two FOR clauses don't nest.
<phil_bb>
beach: thanks, that works, but I seem to be lost as to what's meant in the docs now
<flip214>
phil_bb: perhaps you want EQUALP to ignore character case? Or STRING-EQUAL?
<phil_bb>
probably, but I'm not too worried about it at this point, I just want to wrap my head around loop right now
<gilberth>
And you might avoid duplicates. I won't say APPEND but something like (LOOP FOR C IN *ISO-COUNTRY-CODES* WHEN (LOOP FOR (NIL V) ON C BY #'CDDR THEREIS (EQUAL C QUERY)) COLLECT C) or go functional with sequence functions.
<flip214>
is *iso-country-codes* a plain list like '("Afghanistan" "AF" "Albania" "AL" ...) or an ALIST like '(("Afghanistan" . "AF") ("Albania" . "AL") ...) ??
<ixelp>
6.1 The LOOP Facility | Common Lisp Nova Spec
<phil_bb>
Reading this I was under the impression that each :for clause was causing them to be executed sequentially but this only applies to the variable initialization
<phil_bb>
Yeah as I mentioned, beach's solution works. It was just unintuitive because I thought loop worked differently to how I expected based on my low reading level.
<beach>
flip214: Your :collect is not correctly indented. Are you not using slime-indentation?
attila_lendvai has joined #commonlisp
<flip214>
beach: right now only at a dumb terminal, sorry.