I need to fill a list with pairs, for example: ((x 10)(z 5)).
My current method:
;;send the current list, and an id value pair
(define (setID idList ID VAL)
(cond
;;if the list is null, add the pair
((null? idList) (cons '(ID VAL) '()))
;; if the ID already exists, overwrite it
((equal? ID (car(car idList))) (cons '((cdr idList)) VAL))
;; continue the search
(else (setID (cdr idList) ID VAL))
)
)
I realize I also need to use cons
to keep the list in tact, but the first problem is that when I do something like (setID z 5)
, the returned list is exactly: ((id val))
. Obviously, it needs to be ((z 10))
. Is there anyway to do such a thing?
There are three main problems with your code:
(cons '(ID VAL) '()))
you're building a new pair with the value (ID VAL)
- that is, the first element is the symbol ID
and the second is the symbol VAL
. That's not what you want, you want the value of ID
and the value of VAL
. Make sure you understand the way a quote
worksID
you have to cons the newly modified pair with the rest of the listcons
it to the output. Remember: we're building the answer as we go traversing the listThis is what I mean:
;;send the current list, and an id value pair
(define (setID idList ID VAL)
(cond
;;if the list is null, add the pair
((null? idList) (cons (list ID VAL) '()))
;; if the ID already exists, overwrite it
((equal? ID (car (car idList))) (cons (list ID VAL) (cdr idList)))
;; continue the search
(else (cons (car idList) (setID (cdr idList) ID VAL)))))
And don't forget that the list returned after executing this procedure is a new one, you have to store it somewhere or pass it along as a parameter if you want to keep adding elements to it - because the list originally received as parameter remains unmodified. Now the procedure works as expected:
(setID '() 'x 10)
=> '((x 10))
(setID '((x 10)) 'y 20)
=> '((x 10) (y 20))
(setID '((x 10) (y 20)) 'x 30)
=> '((x 30) (y 20))