2013-11-28 2 views
2

Если я хочу использовать карту в двух списках, lst1 и lst2, и я хочу применить что-то к каждому элементу lst2, используя каждый элемент lst1, как бы я это сделал?Что касается карты в схеме

Например, если я хочу, чтобы создать список, где (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

Можете ли вы более четко объяснить, что хотите? Похоже, вам может понадобиться декартово произведение, а не отображение. Если 'lst1' is' (list 1 2) 'и' lst2' is '(list 'a' b)', что вы хотите получить? – svk

+0

@svk Ваша интуиция оказалась правильной, похоже, на основе обновления OP. –

+3

Вы уверены, что не хотите '(список (список 1 'a) (список 1' b) ...)' –

ответ

2

Теперь вопрос ясен - вы ищете для cartesian product; попробуйте это:

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

Или, если вы используете ракетки, вот простое решение (как это было предложено 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)) 
+0

@ user3044487 Это то, что вам нужно? ожидаемый результат, как указано в вопросе, немного запутан. –

+0

Звучит из обновления вопроса, что все потребности OP являются декартовым продуктом. –

+0

Ваша реализация «декартова продукта» в вашей ракетке слишком сложна. Таким образом, моя версия: '(define (cartesian-product lst1 lst2) (для */list ((x lst1) (y lst2)) (список xy)))' –

Смежные вопросы