Racket/Scheme - 将函数应用于列表列表中的每个元素

Racket/Scheme - Applying a function to each element in a list of lists

我是一名物理专业学生,正在学习数学 class 和编程(我注册了数学),但我以前从未用任何语言编写过代码,所以关于 Racket 的一切对我来说都是全新的。到目前为止 class 的目标是获取与集合相关的函数并将它们转换为 Racket 程序。这些功能之一是获取列表的列表并删除每个元素的第一项:

f({(0, 1, 0), (1, 0, 0), (1, 1, 1)...} = {(1, 0), (0, 0), ( 1, 1)...}

到目前为止我已经把这个作为一个程序:

(define (procA set)
  (cond
    ((null? set) '())
    ((rest (first set)))
    ((procA (rest set)))))

当我 运行 程序时,它返回并应用了正确的函数,但只有第一个元素,例如如何

(procA '((0 1 0) (1 0 0) (1 1 1)))

返回为'(1 0)。它是某种 "map" 函数,还是完全不同的东西?我以为最后一行会处理列表的其余部分,但事实并非如此。

正如@uselpa 评论的那样,它与 map rest 相同。如果你想实现它,你需要使用递归和cons一起得到结果列表。

我认为最直接的方法是使用 if 找到空列表的基本情况:

(define (procB set)
  (if (null? set)
      '()
      (cons (rest (first set)) (procB (rest set)))))

如果要用cond,一样可以写成

(define (procC set)
  (cond
    ((null? set) '())
    (else (cons (rest (first set)) (procC (rest set))))))

(在这种情况下 else 不是必需的:如果省略它也将是下面描述的 "test expression without body" 情况。注意我只是说删除 else 这个词,不是它后面的表达式。)

也就是说,您的代码中唯一缺少的是 cons。在您的代码中,最后一条语句(带有递归)将永远不会被执行,因为 cond 选择第一个为真的测试表达式(并且 (rest non-empty-list) 是一个 "truthy" 值。类似的示例:

> (cond 
    ((= 1 2) 0)
    ((+ 3 4))
    ((+ 5 6)))
7

其中第一个测试表达式为假,因此它继续到第二个为真,并且由于它没有正文,测试表达式的结果成为 cond 的结果。第三个测试表达式永远不会执行。

(define (exclude list)
  (if (empty? list) '""
  (let ((r (rest list)) (f (rest (first list))))
   (~a f (exclude r))

)))
(exclude '( (3 4 5) ( 6 7 8) ( 9 10 11)))

;(4 5)(7 8)(10 11)