Search code examples
listrecursionracketnested-lists

Sum a list of lists in Racket


What is an elegant or idiomatic way to get the sum of a list of lists in Racket? (I am new to Racket).

Here's what I put together but it requires two functions, ideally it would only need one:

(define (count-reps-per-round lst)
  #| a partial solution with recursion, 
  only adds the subtotal
  of each list and returns a new list
  |#
  (cond
    [(empty? lst) empty]
    [else (cons (apply + (first lst))
          (count-reps-per-round (rest lst)))]))


(define (reps-per-workout lst)  ; would be nice to combine with above into one function
  (apply + (count-reps-per-round lst)))

(define results `(
                  (28 25 34 18)
                  (22 21 30 20)
                  (19 16 24 16)
                  (18 17 20 19)))

(display(count-reps-per-round results))  ; (105 93 75 74)
(= (reps-per-workout results) 347)  ; #t

I would also be interested in any solution that doesn't require nested lists.


Solution

  • There's nothing wrong with splitting a complex problem in multiple helper functions, in fact this is encouraged when doing functional programming. But also we're encouraged to reuse built-in procedures whenever possible, for example we can write the solution to your problem in a single line by carefully combining map and apply:

    (define (reps-per-workout lst)
      (apply + (map (lambda (sl) (apply + sl)) lst)))
    

    It works as expected:

    (define results
      '((28 25 34 18)
        (22 21 30 20)
        (19 16 24 16)
        (18 17 20 19)))
    
    (reps-per-workout results)
    => 347