Racket中求列表的列表之和的优雅写法(新手求教)
Racket嵌套列表求和的优雅写法
合并为单一函数的方案
你当前的两个函数可以合并成一步完成总合计算,无需先生成子列表和的列表再二次求和。以下是几种Racket惯用的实现方式:
1. 高阶函数组合(简洁直观)
先用map计算每个子列表的和,再通过apply +将这些子和累加:
(define (total-reps lst) (apply + (map (lambda (sublist) (apply + sublist)) lst)))
测试示例:
(total-reps results) ; 输出347
2. foldl直接累加(高效无中间列表)
若不想生成存储子列表和的中间列表,foldl可以直接遍历每个子列表,将其和累加到初始值0上,避免额外内存开销:
(define (total-reps lst) (foldl (lambda (sublist acc) (+ (apply + sublist) acc)) 0 lst))
3. 递归实现(贴合你的初始思路)
如果偏好递归写法,可将两个函数的逻辑合并为一个递归过程:
(define (total-reps lst) (cond [(empty? lst) 0] [else (+ (apply + (first lst)) (total-reps (rest lst)))]))
同时获取子列表和与总合
若有时既需要每个子列表的和,又需要总合,无需拆分两个函数,可通过values返回多个结果:
(define (reps-info lst) (let ([per-round (map (lambda (sublist) (apply + sublist)) lst)]) (values per-round (apply + per-round))))
调用时用let-values接收两个返回值:
(let-values ([(per-round total) (reps-info results)]) (display per-round) ; 输出(105 93 75 74) (= total 347)) ; 返回#t
非嵌套列表的求和方案
如果输入是无嵌套的扁平列表,求和方式更简单,以下两种都是惯用写法:
; 方式1:apply + 直接展开列表元素作为参数 (apply + '(28 25 34 18 22 21)) ; 输出148 ; 方式2:foldl 逐个累加元素 (foldl + 0 '(28 25 34 18 22 21)) ; 输出148
内容的提问来源于stack exchange,提问作者Ike
相关产品推荐
相关产品推荐

