You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Racket ISL如何用foldr结合local/lambda单次遍历求偶数平方

基于foldr的单次遍历偶数平方函数实现

你原先用map+filter组合的实现逻辑正确,但确实会对列表做两次遍历:第一次遍历全表筛选出所有偶数生成中间列表,第二次遍历中间列表对每个偶数做平方运算。要实现单次遍历、不对奇数做冗余平方计算的需求,直接用foldr在折叠步骤中同时完成判断、计算、拼接三个动作即可,完全符合Racket ISL的语法要求。

实现思路

foldr作为右折叠函数,会逐个处理列表中的每个元素,每一步拿到当前处理的元素和后续元素处理完成后的结果列表:

  • 如果当前元素是偶数:计算它的平方,把平方值通过cons拼到结果列表的头部
  • 如果当前元素是奇数:直接跳过,不执行任何平方计算,直接返回后续结果列表
    整个过程只遍历原列表一次,没有中间列表生成,所有非偶数元素完全不会触发平方运算。

代码实现

lambda版本(最简洁)

直接在foldr参数位置写匿名处理函数,不需要额外的内部定义:

; even-squares-only : [List-of Number] -> [List-of Number]
; 返回输入列表中所有偶数的平方,单次遍历无冗余计算
(define (even-squares-only lon)
  (foldr (λ (current rest-res)
           (if (even? current)
               (cons (sqr current) rest-res)
               rest-res))
         '()
         lon))

local版本(适合逻辑更复杂的场景)

如果后续要扩展处理逻辑,可以用local把单步处理逻辑封装成内部命名函数,可读性更强:

; even-squares-only : [List-of Number] -> [List-of Number]
; 返回输入列表中所有偶数的平方,单次遍历无冗余计算
(define (even-squares-only lon)
  (local (; 单步处理:判断当前元素是否为偶数,是则拼接平方值到结果,否则跳过
          (define (deal-current current rest-res)
            (if (even? current)
                (cons (sqr current) rest-res)
                rest-res)))
    (foldr deal-current '() lon)))

实现特性

  • 输出结果和原map+filter实现完全一致:右折叠的处理顺序保证了偶数的相对顺序和原列表一致,比如输入(list 1 2 3 4 5 6)时,两个版本的返回值都是(list 4 16 36)
  • 无冗余计算:所有奇数都不会执行sqr运算,也不会生成额外的中间过滤列表
  • 遍历效率更高:仅对原列表做一次完整遍历,时间复杂度和原实现同为O(n),但常数项更低

内容的提问来源于stack exchange,提问作者user19636979

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:09:20