在我正在进行的练习考试中,有一个问题要求创建一个过程,该过程采用列表并创建一个新列表,其中包含旧列表中每个元素的两个,同时保留顺序。他们提供的例子:
(double-duplicate (list 1 2 3 4 4 5))
产生
(1 1 2 2 3 3 4 4 4 4 5 5)
我设法找到了一个使用map和flatten的解决方案:
(define (flatten list)
(cond ((null? list) '())
((list? (car list)) (append (flatten (car list)) (flatten (cdr list))))
(else (cons (car list) (flatten (cdr list))))))
(define (double-duplicate ls)
(define (helper list1 list2)
(flatten (map list list1 list2)))
(helper ls ls))
虽然它确实有效,但我觉得它不是最有效的解决方案,因为我使用的是带有3个参数的地图形式,我不喜欢必须编写第二个程序(展平)的想法摆脱多余的括号。谁能想到更好的方法呢?关于我怎么写它,我有点迷茫。我很欣赏任何想法。
*注意:我正在使用麻省理工学院计划。
答案 0 :(得分:2)
这个更适合accumulate
:
(define (double-duplicate lst)
(accumulate (lambda (e acc)
(cons e (cons e acc)))
'()
lst))
同样,假设accumulate
的定义与之前的问题相同 - 也就是说,作为右侧的折叠。
答案 1 :(得分:1)
您使用的是Racket吗?如果是这样,您可以使用append-map
:
(define (double-duplicate lst)
(append-map (lambda (x) (list x x)) lst))
append-map
类似于Scala的flatmap
。
如果您需要,请编写自己的append-map
版本并不难:
(define (append-map func lst)
(fold-right (lambda (e r)
(append (func e) r)) '() lst))