Inserting into a nested list (with assoc)

Q&A's, tips, howto's
Locked
kanen
Posts: 145
Joined: Thu Mar 25, 2010 6:24 pm
Contact:

Inserting into a nested list (with assoc)

Post by kanen »

I have a list:

Code: Select all

(set (global 'me) '(
  (80 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101))) )
  (25 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101))) )
  ))
I can get to it fairly easily;

Code: Select all

(assoc 80 me)                     ; returns all "80" results
(assoc (list 80 1010) me)         ; returns all "80" + "1010" results
(last (assoc (list 80 1010) me))  ; returns the list for 80 + 1010
My question is, how do I insert a list into the results from (last (assoc (list 80 1010) me)) easily and quickly? I can get the results, insert into them, then re-insert the new list... but, I'd rather do this all-at-once.
. Kanen Flowers http://kanen.me .

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: Inserting into a nested list (with assoc)

Post by cormullion »

Perhaps set-ref can help:

Code: Select all

(set-ref (assoc (list 80 1010) me) me (append $it (list "more stuff")))

Code: Select all

(
 (80 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)) 
   "more stuff")) 
 (25 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)))
 ))

kanen
Posts: 145
Joined: Thu Mar 25, 2010 6:24 pm
Contact:

Re: Inserting into a nested list (with assoc)

Post by kanen »

Thanks!

I've never even used (set-ref) before, in all my years of newLisp. Everyday, as they say... you learn a thing.
. Kanen Flowers http://kanen.me .

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: Inserting into a nested list (with assoc)

Post by cormullion »

set-ref is nearly as awesome as set-ref-all with match wild-cards! :)

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

Re: Inserting into a nested list (with assoc)

Post by Lutz »

This can be made even simpler. The example searches me twice. First assoc searches in me then set-ref does search in me again for the expression found by assoc.

In this case you could just use setf:

Code: Select all

(setf (assoc '(80 1010) me)  (append $it (list "more stuff")))

me =>
((80 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)) 
   "more stuff")) 
 (25 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)))))
The place reference returned by assoc can be used by setf

.. and you can make it even shorter using push:

Code: Select all

(push "more stuff" (assoc '(80 1010) me) -1)

me =>
((80 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)) 
   "more stuff")) 
 (25 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)))))
push also can use place references and you can better control where to exactly put the new piece:

Code: Select all

(push "more stuff" (assoc '(80 1010) me) -1 -1)

me =>
((80 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101) 
    "more stuff"))) 
 (25 (1010 ((84 114 117 115 116 80 105 112 101 73 115 65 119 101 115 111 109 101)))))

in this case, the new element is pushed one nesting level higher.

Locked