2012-01-30 3 views
1

Я ищу краткую схему для отображения вариационной функции в нескольких списках, но вместо того, чтобы передавать списки как отдельные аргументы, как в MAPCAR, я хочу передать один список, состоящий из любого количества списков, и сопоставить их списки. Я не знаю заранее, сколько списков содержится в прилагаемом списке, поэтому я не могу его разрушить.Как сделать краткую карту через список списков?

Я пробовал комбинировать MAPCAR и APPLY различными способами, но не могу понять это. Должен ли я отказаться от использования MAP и просто написать итерацию явно?

Вот функция, которая делает то, что я хочу:

(defun map-within (fn list-of-lists &optional(maptype #'mapcar)) 
    "Map FN on the lists contained in LIST-OF-LISTS" 
    (cond ((null list-of-lists) nil) 
    ((null (cdr list-of-lists)) (car list-of-lists)) 
    (t 
    (funcall maptype fn 
     (car list-of-lists) 
     (map-within fn (cdr list-of-lists) maptype))))) 

где

(map-within #'+ '((1 2 3) (10 20 30) (100 200 300))) => (111 222 333) 

Есть некоторое магическое применение лямбды сделанной из карты, которые могли бы выразить это только с одной линией?

ответ

4

Вы можете использовать apply так:

(apply #'mapcar #'+ '((1 2 3) (10 20 30) (100 200 300))) 
=> (111 222 333) 
+0

Спасибо, что было намного меньше волшебно, чем я ожидал, и, очевидно, она не пришла мне в голову, чтобы просто попробовать. У меня было мнение, что APPLY взял два аргумента, функцию и список и назвал функцию в элементе списка как args, когда на самом деле он вызывает функцию на остальных аргументах при обработке последнего специально. –

+0

@PaulRichter: Да, вы должны посмотреть на ['list *'] (http://www.lispworks.com/documentation/HyperSpec/Body/f_list_.htm). – Daimrod

+1

возможно работает только для списков до CALL-ARGUMENTS-LIMIT, так как в решении используется APPLY –

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