2016-11-13 4 views
0

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

(3 4) (3 5 6) => (9 15 18 12 20 24)

это код, который я придумал, но я получаю ошибку, которая говорит мне, что у меня слишком мало аргументов для карты.

(defun multip (lst lst2) 
    ;this is a function to flatten the result 
    (defun flatten (tree) 
    (let ((result '())) 
     (labels ((scan (item) 
      (if (listp item) 
       (map nil #'scan item) 
       (push item result)))) 
        (scan tree)) 
         (nreverse result))) 
(flatten (map (lambda (i) (map (lambda (j) (* i j)) lst)) lst2)) 
) 

    (write (multip '(3 4 6) '(3 2))) 

Я не могу понять, что я делаю неправильно. Я ценю ваш комментарий.

+0

FYI, вы можете использовать использовать полевую продукт: '(Alexandria: карта-продукта # '*' (3 4)«(3 5 6)) ' – coredump

ответ

3

Вы должны использовать mapcar вместо map:

(mapcar (lambda (i) (mapcar (lambda (j) (* i j)) lst)) lst2)) 

Это две различные функции: mapcar отображает функцию на один или несколько списков, и требует, по меньшей мере, два аргумента, в то время как map эквивалент, но и для любого (например, векторы) и требует дополнительного аргумента, определяющего тип результата. См. Ссылку для maphere, а также ссылку для mapcarhere.

Стиль

Вы используете defun внутри другого defun: это не хороший стиль, так как каждый раз, когда multip называется переопределяет глобально функцию flatten. Вы должны либо определить flatten извне, только один раз, или использовать локальную декларацию функции с flet или labels (как для внутренней функции scan внутри flatten.)

Для альтернативных и более простых определений flatten, вы можете увидеть this question в ТАК.

+0

Благодаря хорошо работал , – Shahryar

+0

Да, вы правы в отношении стиля, я буду читать ресурсы, которые вы представили мне. еще раз спасибо. – Shahryar

4

Вам не нужно сгладить список, если вы создали плоский список.

Использование MAPCAN:

CL-USER 4 > (flet ((mult (a b) 
        (mapcan #'(lambda (a1) 
           (mapcar (lambda (b1) (* a1 b1)) 
             b)) 
          a))) 
       (mult '(3 4) '(3 5 6))) 
(9 15 18 12 20 24)