Reputation: 79
;; An association list (al) is either
;; empty or
;; (cons (list k v) alst), where
;; k is a nat (the key),
;; v is a string (the value), and
;; alst is an association list (al)
updatestring takes an association list, a number (findnum) and a string (newstring) and if there is a number the same as findnum in the association list, then it replaces the string in the list with newstring.
(check-expect(updatestring empty 3 "hi") (list (list 3 "hi")))
(check-expect(updatestring (list (list 1 "hi")(list 5 "wow")) 5 "new")(list (list 1 "hi")(list 5 "new")))
(check-expect(updatestring (list (list 1 "hi")(list 5 "wow")) 2 "nice")(list (list 2 "nice") (list 1 "hi")(list 5 "wow")))
I'm having trouble with the code as this is what I have.
(define (al-update alst akey avalue)
(cond
[(empty? alst) (list (list akey avalue))]
[(= (first(first alst)) akey) (al-update (rest alst) akey avalue)]
[else (list(list akey avalue alst))]))
The problem is that my code returns
(list (list 5 "new" (list (list 1 "hi") (list 5 "wow"))) instead of (list (list 1 "hi") (list 5 "new"))
and
(list(list 2 "nice" (list (list 1 "hi") (list 5 "wow")))) instead of (list (list 2 "nice") (list 1 "hi")(list 5 "wow")))
Any tips and answers would be very much appreciated thanks!
Upvotes: 0
Views: 498
Reputation: 310
It says "if there is a number the same as findnum in the association list, then it replaces the string in the list with newstring", but in your example if the given number does not exist you add that into the list.
(check-expect (updatestring (list (list 1 "hi") (list 5 "wow")) 2 "nice")
(list (list 2 "nice") (list 1 "hi") (list 5 "wow")))
(check-expect(updatestring empty 3 "hi") (list (list 3 "hi")))
Code and the examples (tests) should be these:
(define (al-update alst akey avalue)
(cond
[(empty? alst) empty]
[(= (first (first alst)) akey) (cons (list (first (first alst)) avalue)
(al-update (rest alst) akey avalue))]
[else (cons (first alst) (al-update (rest alst) akey avalue))]))
(check-expect (updatestring empty 3 "hi") empty)
(check-expect (updatestring (list (list 1 "hi") (list 5 "wow")) 5 "new")
(list (list 1 "hi") (list 5 "new")))
(check-expect (updatestring (list (list 1 "hi") (list 5 "wow")) 2 "nice")
(list (list 1 "hi") (list 5 "wow")))
(check-expect (updatestring (list (list 1 "hi") (list 5 "wow") (list 2 "bad")) 2 "nice")
(list (list 1 "hi") (list 5 "wow") (list 2 "nice")))
By the way "car" is equivalent to "first" and "cdr" is "rest".
Upvotes: 0
Reputation: 70265
Your recursive structure needs to be something like this:
(define (al-update alist akey avalue)
(if (empty? alist) ; base, end recusion
'()
(cons (let ((key+value (first alist))) ; element, one-by-one
(if (= ...)
...
...))
(al-update (rest alist) akey avalue)))) ; recursion
In your code there are a number of problems. The else
clause needs to recurse over the rest of the list. In the =
clause you need to do the substitution and recurse. In my code above, I combined the two clauses that recurse.
Upvotes: 1