将列表中的元素配对

时间:2016-04-16 22:46:50

标签: scheme lisp racket

我正在使用以下规范在Scheme中创建一个名为pair-elements的函数。它需要一个多个子列表的列表,每个子列表必须只有两个元素(我现在不会检查这个)。它返回一个包含两个子列表的列表,一个列表包含每个给定子列表的第一个元素,另一个列表包含第二个元素。以下是它应该做的一个例子:

>(对元素'((a b)(c d)(e f)))
((a c e)(b d f))

这是我到目前为止所拥有的。我已经能够使用以下代码成功创建第一个子列表:

(define (pair-elements x)
    (if (null? x)
    null
    (cons (caar x) (pair-elements (cdr x)))))

经过测试,结果如下:
>(对元素'((a b)(c d)(e f)))
(a c e)

它朝着正确的方向迈出了一步,但我无法弄清楚如何做第二部分并将它们放入列表中。我的所有尝试都导致了非常难看的输出。例如,我的一次尝试:

(cons (cons (caar x) (pair-elements (cdr x))) (cons (cdar x) (pair-elements (cdr x))))))

获取输出((a(c(e)(f))(d)(e)(f))(b)(c(e)(f))(d)(e)(f)) ,这显然是远离。

任何人都可以帮我完成这个功能吗?我是Scheme的新手,我当然需要知道如何做这样的事情。列出子列表是我特别难以克服的。

1 个答案:

答案 0 :(得分:3)

你的实现基本上是重新发明轮子 - 如果你使用内置程序map,这会更容易,这可以做你想要的;您只需要将要应用于输入列表的每个元素的过程作为参数传递(在这种情况下为firstsecond):

(define (pair-elements lst)
  (list                 ; create a new list with the two sublists
   (map first lst)      ; sublist of first elements of input list
   (map second lst)))   ; sublist of second elements of input list

我们可以更进一步,并使用map可以接收多个列表作为输入的事实:

(define (pair-elements lst) ; process input list element-wise on each
  (apply map list lst))     ; sublist and create a list with them

无论哪种方式,它都按预期工作:

(pair-elements '((a b) (c d) (e f)))
=> '((a c e) (b d f))