关于计划中的地图

时间:2013-11-28 18:32:38

标签: map scheme

如果我想在两个列表lst1lst2上使用Map,我想使用lst1的每个元素对lst2的每个元素应用一些东西,我该怎么做?

例如,如果我想创建一个列表(first lst1)附加到(first lst2)... (last lst2),然后(second lst2)附加到(first lst2) ... (last lst2)。我该怎么办?

我尝试在两个列表中使用地图。

(define (... lst1 lst2)  
  (map (lambda (x y)          
         (if (empty? lst1) empty (cons x (list y))))        
       lst1 lst2))

如果给出了(list 1 2 3)(list 'a 'b 'c)列表,我会得到(list 1 'a (list 2 'b) (list 3 'c))。如何更改它以便我得到(list 1 'a (list 1 'b)...

谢谢!

编辑:抱歉令人困惑的措辞。 这是我想要的列表(list 1 2)(list 'a 'b 'c)

(list 1 'a (list 1 'b) (list 1 'c) (list 2 'a) (list 2 'b) (list 2 'c))

1 个答案:

答案 0 :(得分:2)

现在问题很清楚了 - 你正在寻找一个cartesian product;试试这个:

(define (cartesian-product lst1 lst2)
  (apply append
         (map (lambda (x)
                (map (lambda (y)
                       (list x y))
                     lst2))
              lst1)))

或者如果您使用的是Racket,这里有一个更简单的解决方案(正如Chris在评论中所建议的那样):

(define (cartesian-product lst1 lst2)
  (for*/list ((x lst1) (y lst2))
    (list x y)))

对于更通用的解决方案,此实现适用于任意数量的列表:

(define (cartesian-product . lsts)
  (foldr (lambda (lst acc)
           (for*/list ((x (in-list lst))
                       (y (in-list acc)))
             (cons x y)))
         '(())
         lsts))

无论如何,像这样使用它:

(cartesian-product (list 1 2) (list 'a 'b 'c))
=> '((1 a) (1 b) (1 c) (2 a) (2 b) (2 c))