0

假设我们有这个列表'( (4 (1 2)) (5 (5 5)) (7 (3 1)) (1 (2 3)))

我正在尝试在 Scheme 中编写 smth 以获得列表中每个元素的第二个元素。所以结果看起来像'( (1 2) (5 5) (3 1) (2 3))

到目前为止我有这个代码..

(define (second  list1)
  (if (null? (cdr list1))
      (cdr (car list1))
      ((cdr (car list1))(second (cdr list1)))))
4

3 回答 3

4

这是一个简单的解决方案:

(define (seconds lst)
  (map cadr lst))

通常,当您要转换列表的每个元素时,map就是要走的路。

于 2013-10-25T21:24:54.567 回答
2

您需要做的就是map将内置函数添加second到列表中lst

(map second lst)
于 2013-10-26T04:18:25.637 回答
1

您的错误是您缺少操作员,也许cons. 如果你看结果:

((cdr (car list1))(second (cdr list1)))

因此,Scheme 期望 (cdr (car list)) 是一个过程,因为它在表单中的操作员位置,但因为它不是你得到一个错误。此外(cdr (car x))==cdar不会取每个元素中的第二个元素,而是每个元素的尾部。cadar是你正在寻找的。

(define (second  list1)00+
  (if (null? (cdr list1))
      (cons (cadar list1) '())
      (cons (cadar list1) (second (cdr list1)))))

空列表将失败。为了解决这个问题,你让 consequemt 处理每个元素,并且只停止基本情况:

(define (second  list1)
  (if (null? list1)
      '()
      (cons (cadar list1) (second (cdr list1)))))

列表的结果将是相同的。有一个过程叫做map。它支持多个列表参数,但其中一个的实现是:

(define (map fun lst)
  (if (null? lst)
      '()
      (cons (fun (car lst)) (map fun (cdr lst)))))

看起来很熟悉?两者都根据每个元素制作一个列表,但map都是通用的。因此我们应该尝试(fun (car lst))做同样的事情(cadar lst)

(define (second lst)
  (map cadr lst)) ; (cadr (car x)) == (cadar x)

你有它。克里斯打败了我,但我想评论使用缩写的其他答案之一second。它在球拍/基地和库 SRFI-1 中定义,但在最后的方案报告中没有提到。即,某些实现可能需要导入额外的库才能使其工作。

于 2013-10-26T14:36:16.093 回答