将元素插入列表列表中的子列表的开头

时间:2013-11-14 16:55:35

标签: scheme lisp racket

我在执行任务时遇到了一些麻烦。我必须创建一个请求列表和元素列表的过程,然后继续将元素添加到每个子列表中的第一个位置。我设法做到了,它看起来像这样:

(define (add-element lst elem)
   (foldr cons lst (list elem)))

(define (insert-first lst1 x)
  (cond
   [(empty? lst1) empty]
   [else (local [(define insert (add-element(first lst1) x))]
        (cons insert (insert-first (rest lst1) x)))]))

因此,如果您要输入(insert-first '((a b) (c d)),最终会得到(list (list 'x 'a 'b) (list 'x 'c 'd))

唯一的问题是我需要使用maplocal对流程进行编码。后者我认为我已经完成但我不能为我的生活找到一种方法来使用map

3 个答案:

答案 0 :(得分:5)

(define (insert-first elt lst)
  (map (lambda (x)
         (cons elt x))
       lst))

然后

(insert-first 'x '((a b) (c d)))
=> '((x a b) (x c d))

答案 1 :(得分:0)

(define (insert-first lst elem)
   (foldr (lambda (x y) (cons (cons elem x) y)) '() lst))

关闭您的解决方案,但是地图更适合问题而不是折叠,因为您想要对列表的每个元素执行某些操作。如果要通过将函数连续应用于该列表的元素来累积值,请使用折叠。

答案 2 :(得分:0)

foldr embodies某种递归模式,

(foldr g init [a,b,c,...,z]) 
= (g a (foldr g init [b,c,...,z]))
....
= (g a (g b (g c ... (g z init) ...)))

如果我们手动展开foldr函数定义中的add-element调用,我们就会

  (add-element lst elem)
  = (foldr cons lst (list elem)) 
  = (cons elem (foldr cons lst '()))
  = (cons elem lst)

然后,查看您的insert-first函数,我们发现它也跟随foldr递归模式,

(insert-first lst1 x) 
= (foldr (lambda(a r)(cons (add-element a x) r)) empty lst1) 
= (foldr (lambda(a r)(cons (cons x a) r)) empty lst1)

但是(foldr (lambda(a r) (cons (g a) r)) empty lst) === (map g lst),因为将子词与cons结合起来是建立一个列表,这是map所做的;所以我们得到

(insert-first lst1 x) = (map (lambda(a)(cons x a)) lst1)

所以我们可以写

(define (insert-first lst1 x)
  (local [(define (prepend-x a) (cons ... ...))]
    (map ... ...)))