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

MIT-Scheme中如何按索引过滤?以P16习题为例求函数式实现

在MIT-Scheme中实现按索引过滤(删除第N个元素)的函数式方法

要实现类似你Python示例中的按索引过滤逻辑,MIT-Scheme没有内置的enumerate函数,但可以通过构造带索引的元素对,结合filter和map来实现,或者用fold(折叠)来更简洁地处理索引逻辑。以下是几种方案:

1. 模拟enumerate + 过滤映射

先实现一个简单的enumerate函数,生成(索引 . 元素)的配对列表,再过滤掉符合删除条件的配对,最后提取元素:

; 生成带索引的元素对列表,索引从0开始
(define (enumerate lst)
  (let loop ([lst lst] [idx 0])
    (if (null? lst)
        '()
        (cons (cons idx (car lst)) (loop (cdr lst) (+ idx 1))))))

; 定义删除第N个元素的函数
(define (drop-every-nth lst n)
  (map cdr
       (filter (lambda (pair)
                 ; 过滤掉位置(索引+1)能被n整除的元素
                 (not (zero? (modulo (+ (car pair) 1) n))))
               (enumerate lst))))

; 测试
(display (drop-every-nth '(a b c d e f g h i j k) 3))
; => (a b d e g h j k)

2. 用fold-left实现更简洁的版本

利用fold-left(MIT-Scheme内置)来遍历列表,同时跟踪当前元素的位置,避免显式递归:

(define (drop-every-nth lst n)
  (reverse
   (fold-left
    (lambda (acc elem)
      ; 累加器acc是反向的结果,当前元素的位置是累加器长度+1(从1开始计数)
      (let ([pos (+ (length acc) 1)])
        (if (zero? (modulo pos n))
            acc ; 跳过第n个元素
            (cons elem acc)))) ; 保留元素,加入累加器
    '()
    lst)))

; 测试
(display (drop-every-nth '(a b c d e f g h i j k) 3))
; => (a b d e g h j k)

3. 紧凑的匿名函数写法

如果不想单独定义enumerate,可以把索引生成逻辑直接整合到过滤过程中:

(display
 (map cdr
      (filter (lambda (pair) (not (zero? (modulo (+ (car pair) 1) 3))))
              (let loop ([lst '(a b c d e f g h i j k)] [idx 0])
                (if (null? lst) '() (cons (cons idx (car lst)) (loop (cdr lst) (+ idx 1))))))))
; => (a b d e g h j k)

这些方法都符合函数式编程的风格,避免了可变状态,和你Python中用enumerate+filter/列表推导式的思路一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:41:32