Jump to content
Jeff

Mapcar Confusion

Recommended Posts

Jeff

Hi All,

 

I am trying to improve my skills by using mapcar & lambda more frequently and ran across this code for averaging a set of points on Lee Mac's website.

(defun averagepoint ( lst / n )
    (setq n (float (length lst)))
    (mapcar '/ (apply 'mapcar (cons '+ lst)) (list n n n))
)

The part that is making my head explode is the (apply 'mapcar (cons '+ lst))

 

Here's my limited understanding. Given the 'lst' variable is set to '((0 1) (1 2) (2 3))  I understand that the 'cons' part evaluates to (+ (0 1) (1 2) (2 3)). No problem there.

 

How on earth does the mapcar and apply sum the x values and the y values?  I know it does because  (apply 'mapcar (cons '+ lst))

 

evaluates to (3 6). I've played with this for hours trying to figure it out.

 

Thanks in advance for any help.

 

-Jeff

 

 

Share this post


Link to post
Share on other sites
dlanorh

It's difficult to explain, and I'm sure I'll be corrected.

 

Lst is a list of lists, so you cannot simply (mapcar '+ lst) or (apply '+ lst) as each sub entity is a list, not a number.

 

So using your short example list from above it is the equivalent to (mapcar '+ (car lst) (cadr lst) (caddr lst)) or (mapcar '+ (nth 0 lst) (nth 1 lst) (nth 2 lst)).

 

The (cons '+ lst) forms a new list in a format that mapcar can understand (+ (0 1) (1 2) (2 3)) where + is the function that mapcar needs to apply to the following sub lists list1 ....listn

taking in turn the first element of each sub list followed by the second element, then the third until it reaches a point where one of the sublists is empty.

 

Since mapcar itself is a function this can be applied to a list it understands.

 

run these on the command line in Autocad:  (setq lst '((0 1) (1 2) (2 3)))

 

then  (apply 'mapcar (cons '+ lst)))

 

but try changing (cons '+ lst) to the following (cons '- lst)  (cons '* lst)  (cons 'min lst) (cons 'max lst) and watch what is returned

 

alternatively  (setq lst '(("A" "D") ("B" "E") ("C" "F"))) and (apply 'mapcar (cons 'strcat lst))

  • Like 1

Share this post


Link to post
Share on other sites
Lee Mac

I meant to post this earlier, but the forum was unresponsive.

 

Essentially this -

(apply 'mapcar (cons '+ '((0 1) (1 2) (2 3))))

Is equivalent to:

(mapcar '+ '(0 1) '(1 2) '(2 3))

Which is evaluated as:

(list (+ 0 1 2) (+ 1 2 3))

 

  • Like 1

Share this post


Link to post
Share on other sites
Jeff

Thanks guys. I think I've got it in my head now.

Share this post


Link to post
Share on other sites
myloveflyer
4 hours ago, Lee Mac said:

I meant to post this earlier, but the forum was unresponsive.

 

Essentially this -

(apply 'mapcar (cons '+ '((0 1) (1 2) (2 3))))

Is equivalent to:

(mapcar '+ '(0 1) '(1 2) '(2 3))

Which is evaluated as:

(list (+ 0 1 2) (+ 1 2 3))

 

Lee, your code is simple, I wrote it too cumbersome!
Dlanorh's explanation is comprehensive!
Thank you very much!
The following is what I wrote, so cumbersome!

(setq lst '((0 1) (1 2) (2 3)))
(setq lst_x (mapcar '(lambda (x) (apply '+ (mapcar x lst))) '(car cadr)))
(setq lst_x1 (mapcar '(lambda (x) (apply '+ x)) (apply 'mapcar (cons 'list lst))))

 

Share this post


Link to post
Share on other sites
myloveflyer
4 hours ago, Lee Mac said:

我本打算早些时候发这篇文章的,但是论坛没有回应。

 

本质上是这个-

(apply 'mapcar (cons '+ '((0 1) (1 2) (2 3))))

相当于:

(mapcar '+ '(0 1) '(1 2) '(2 3))

评价如下:

(list (+ 0 1 2) (+ 1 2 3))

 

Lee, can you provide some code for list calculations for us to learn?

Share this post


Link to post
Share on other sites
Lee Mac
9 hours ago, myloveflyer said:

Lee, your code is simple, I wrote it too cumbersome!
The following is what I wrote, so cumbersome!

(setq lst '((0 1) (1 2) (2 3)))
(setq lst_x (mapcar '(lambda (x) (apply '+ (mapcar x lst))) '(car cadr)))
(setq lst_x1 (mapcar '(lambda (x) (apply '+ x)) (apply 'mapcar (cons 'list lst))))

 

 

Don't be too hard on yourself: both of those examples are equally valid approaches to tackling the problem, and demonstrate that you evidently have a good understanding of the use of mapcar, lambda, & apply - well done.

 

9 hours ago, myloveflyer said:

Lee, can you provide some code for list calculations for us to learn?

 

Sorry, I'm not quite sure what you mean by this - if you're looking for a standard set of list manipulation techniques to learn, aside from the basic forms of iteration/recursion (which you may learn from any online tutorial or developer reference), I tend to develop code specfically to fulfill a particular requirement and so the list manipulation varies significantly from function to function.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...