返回列表中每个元素的第二个元素

时间:2013-10-25 21:17:09

标签: list scheme racket

假设我们有此列表'( (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)))))

3 个答案:

答案 0 :(得分:4)

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

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

通常,当您想要转换列表中的每个元素时,map是可行的方法。

答案 1 :(得分:2)

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

(map second lst)

答案 2 :(得分: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)

你有它。 Chris beat me to it,但我想评论使用缩写second的其他答案之一。它在racket / base和库SRFI-1中定义,但在上一个Scheme报告中没有提到。即某些实现可能需要导入额外的库才能使其正常工作。