Arc Forumnew | comments | leaders | submitlogin
How can one modify vals in assoc lists ?
3 points by thaddeus 4509 days ago | 3 comments

  (= mylist '((k1 v1)(k2 v2)(k3 v3)))

  arc>(alref mylist 'k2)

  arc> (push '(k2 v4) mylist)
  ((k2 v4) (k1 v1) (k2 v2) (k3 v3))

  arc>(alref mylist 'k2)
alref always gets the first item so it's works, but one will have a growing list.

Any means to modify the list without having to redefine the whole thing ?

I am pretty sure you can't, but I figured one of you might know a trick...

Thanks, T.

4 points by CatDancer 4509 days ago | link

'assoc will find for you the cons containing the key and value:

  arc> (assoc 'k2 mylist)
  (k2 v2)
so just modify the cons:

  arc> (= ((assoc 'k2 mylist) 1) 'foo)
  arc> mylist
  ((k1 v1) (k2 foo) (k3 v3))


2 points by palsecam 4509 days ago | link

Thaddeus, nothing is impossible :-)! You can do:

   arc> (= mylist '((k1 v1)(k2 v2)(k3 v3)))
   ((k1 v1) (k2 v2) (k3 v3))
   arc> (= (cadr (assoc 'k2 mylist)) 'v4)
   arc> (alref mylist 'k2)
   arc> mylist
   ((k1 v1) (k2 v4) (k3 v3))
'alref is just:

   (def alref (al key) (cadr (assoc key al)))
but you can't directly say "(= (alref mylist 'k2) 'v4)" because 'alref is a function where 'cadr is a bit special. It is a "place". '= understands it and changes the value at this place.

If you want something shorter than "(= (cadr (assoc 'k2 mylist) 'v4)", you can define a macro. For example:

   (mac cassoc (key al) `(cadr (assoc ,key ,al)))

   arc> (= (cassoc 'k2 mylist) 'v5)
   arc> mylist
   ((k1 v1) (k2 v5) (k3 v3))
Or maybe better (why define a macro actually, Arc is cool and gives you ":"):

   arc> (= (cadr:assoc 'k2 mylist) 'v6)
Short enough IMO.


2 points by thaddeus 4509 days ago | link

That'll work!. Thanks both of you. T.