Question

I started learning Racket today so please be patient :)

What I'm trying is to sum numbers (ages in this case) stored inside a struct. So I have this:

(define-struct rec (name age)) ; defining the struct of records

(define r1 (make-rec "Joe" 23))
(define r2 (make-rec "Sue" 13))
(define r3 (make-rec "Ann" 44))

(define reclist (list r1 r2 r3)) ; defining a list of records

I found out how to sum integers, this seems a good way to do that:

(define liste (list 1 2 3 4 5))
(define (sum-list l)
  (cond
    [(empty? l) 0]
    [(+ (first l) (sum-list (rest l)))]))

Now, I have been trying to somehow combine these functions in a way that I can grab the age inside each record and then sum them all but to no avail. I tried different loop constructs but the problem is that it never returns a value but a procedure name.

I know, I'm missing something very basic here but I'm stuck anyway.

Was it helpful?

Solution 2

Altering your code:

(define (sum-list lst . lkey)
  (define key (if (null? lkey) values (car lkey)))
  (cond
    [(empty? lst) 0]
    [(+ (key (first lst)) (sum-list (rest lst) key))]))

Alternative tail recursive version

(define (sum-list lst . lkey)
  (define key (if (null? lkey) car (compose (car lkey) car)))
  (let loop ((acc 0) (lst lst))
    (if (null? lst)
        acc
        (loop (+ acc (key lst)) 
              (cdr lst)))))

Alternate higher order procedure version in one blob:

(define (sum-list lst . lkey)
  (define key (if (null? lkey) values (car lkey)))
  (foldl (lambda (x acc)
           (+ acc (key x)))
         0 
         lst))

Using map to get the values and apply:

(define (sum-list lst . lkey)
  (apply +
         (if (null? lkey) 
             lst 
             (map (car lkey) lst))))

For many elements this might be more effective:

(define (sum-list lst . lkey)
  (foldl +
         0
         (if (null? lkey) 
             lst 
             (map (car lkey) lst))))

All work like this:

(sum-list '(1 2 3 4))          ; ==> 10
(sum-list '((1)(2)(3)(4)) car) ; ==> 10
(sum-list reclist rec-age)     ; ==> 80

OTHER TIPS

Since your sum-list function operates only on numbers you need to project your rec list to a number list. This can be done with a map function. The expression (map rec-age reclist) will yield the number list for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top