Reputation: 165
(define (associate lst)
(if (or (null? lst) (= (length lst) 1))
'()
(cons (cons (car lst) (cadr lst)) (associate (cddr lst)))))
(define (disassociate lst)
;(display (caar lst))
(if (null? lst)
'()
(cons (cons (caar lst) (cdar lst)) (disassociate (cdr lst)))))
(display (disassociate '((a . 1) (b . 2) (c . 3))))
(newline)
(display (associate '(a 1 b 2 c)))
(newline)
OUTPUT:
;; with list
((a 1) ((b 2) ((c 3) ())))
((a . 1) (b . 2))
;; with cons
((a . 1) (b . 2) (c . 3))
((a . 1) (b . 2))
I'm trying to flatten an association list in Scheme
but the brackets
keep turning up even when I change the list
to cons
. Am I doing something wrong?
Upvotes: 3
Views: 186
Reputation: 70135
Your disassociate
line needs to read:
(cons (caar lst) (cons (cdar lst) (disassociate (cdr lst)))))
quasi-quotation! Sometimes these are more clearly implemented using quasi-quotation because quasi-quotation lets you see the resulting list structure.
(define (associate lst)
(if (or (null? lst) (null? (cdr lst)))
'()
`(,(cons (car lst) (cadr lst)) ,@(associate (cddr lst)))))
(define (disassociate lst)
(if (null? lst)
'()
`(,(caar lst) ,(cdar lst) ,@(disassociate (cdr lst)))))
> (associate (disassociate '((a . 1) (b . 2))))
((a . 1) (b . 2))
Note that you could also write the associate
quasi-quotation as:
`((,(car lst) . ,(cadr lst)) ,@(associate (cddr list)))))
but that starts getting harder to read for me even though it makes the association pair explicit.
Upvotes: 3
Reputation: 235984
There's an error in the way you're creating the list in disassociate
. Try this:
(define (disassociate lst)
(if (null? lst)
'()
(cons (caar lst)
(cons (cdar lst)
(disassociate (cdr lst))))))
Or alternatively, using list*
:
(define (disassociate lst)
(if (null? lst)
'()
(list* (caar lst)
(cdar lst)
(disassociate (cdr lst)))))
The above assumes that the association list is using cons
to stick together the values, notice how the output list is created by cons
ing the first element, then the second and then calling the recursion. On the other hand, if the association list was created using list
to stick together the values, then this is the way to disassociate it:
(define (disassociate lst)
(if (null? lst)
'()
(cons (caar lst)
(cons (cadar lst) ; here's the change
(disassociate (cdr lst))))))
Or alternatively:
(define (disassociate lst)
(if (null? lst)
'()
(list* (caar lst)
(cadar lst) ; here's the change
(disassociate (cdr lst)))))
A more idiomatic solution would be to use higher-order procedures to process the input list. Here's how, using foldr
for the two association list variants described in the question:
; associations created with cons
(define (disassociate lst)
(foldr (lambda (pr ac) (list* (car pr) (cdr pr) ac))
'()
lst))
; associations created with list
(define (disassociate lst)
(foldr (lambda (pr ac) (list* (car pr) (cadr pr) ac))
'()
lst))
Upvotes: 3