Composing a multi-level 'assoc call

Notices and updates
Locked
Tim Johnson
Posts: 253
Joined: Thu Oct 07, 2004 7:21 pm
Location: Palmer Alaska USA

Composing a multi-level 'assoc call

Post by Tim Johnson »

When I execute the following:

Code: Select all

(set 'lst '(
    (id001 (name "Anne") (addr (country "USA") (city "New York")))
    (id002 (name "Jean") (addr (country "France") (city "Paris")))
))
(set 'myargs '('id002 'addr))
;; ('id002 'addr)
(set 'allargs (append '(lst) myargs))
;; (lst 'id002 'addr)
(apply assoc allargs)
I get

Code: Select all

list expected in function assoc : ''id002
Whereas

Code: Select all

(assoc (lst 'id002 'addr))
Yields the expected result.
What is the correct way?
Thanks
Tim

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

When you have multiple keys only the second parenthesized form will work. The flat from and using 'apply' would only work for one key:

Code: Select all

(set 'allargs (list 'id001 lst))

(apply assoc allargs) 

=> (id001 (name "Anne") (addr (country "USA") (city "New York")))
In case you have to construct the arguments for the parenthesized multi-key capable form you could do it this way:

Code: Select all

(set 'allargs '((lst 'id002 'addr)))

(eval (cons assoc allargs))

 => (addr (country "France") (city "Paris"))
But why would you do this, when all elements in the parenthesized form can be variables:

Code: Select all

(set 'key1 'id002)
(set 'key2 'addr)

(assoc (lst key1 key2))

=> (addr (country "France") (city "Paris"))

Tim Johnson
Posts: 253
Joined: Thu Oct 07, 2004 7:21 pm
Location: Palmer Alaska USA

Post by Tim Johnson »

Hi Lutz.
My goal is an interface to a context that manages associative lists
of any level.
Thus, rather than use named variables, I'd like to use (args)
- so think (args) instead of myargs.
Unfortunately, I still can't wrap my brain around _that_ approach.
thanks
tim

Tim Johnson
Posts: 253
Joined: Thu Oct 07, 2004 7:21 pm
Location: Palmer Alaska USA

Post by Tim Johnson »

Draft attempt to use more of a 'drill-down' approach

Code: Select all

 (define (hashit)
  (catch
   (let((res lst))
	 (doargs (i)
			 (set 'res (assoc i res))
			 (if (not res) (throw nil))) ;; dead end
	 (throw res)) ;; done
   'res ;; catch it here
   ) res) ;; return here

Locked