Jeff Posted July 7, 2019 Posted July 7, 2019 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 Quote
dlanorh Posted July 8, 2019 Posted July 8, 2019 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)) 1 Quote
Grrr Posted July 8, 2019 Posted July 8, 2019 Check this thread and this example from Lee should make it clear. 1 Quote
Lee Mac Posted July 8, 2019 Posted July 8, 2019 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)) 1 Quote
Jeff Posted July 9, 2019 Author Posted July 9, 2019 Thanks guys. I think I've got it in my head now. Quote
myloveflyer Posted July 9, 2019 Posted July 9, 2019 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)))) Quote
myloveflyer Posted July 9, 2019 Posted July 9, 2019 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? Quote
Lee Mac Posted July 9, 2019 Posted July 9, 2019 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. Quote
Recommended Posts
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.