I want to write a function in lisp that reverses all elements from the list using map functions but I don't have any idea how to start this.. I think I have to use the built in reverse function somehow.. For example if I have the list (1 2 3 (4 5 6 (7 8 9))) I would get (((9 8 7) 6 5 4) 3 2 1) or if I had the list(1 2 3 (4 5) (6 7)) I would get ((7 6) (5 4) 3 2 1) .. Any help is appreciated!
-
From your comments below, it seems that you are describing a recursive problem, for which the simplest solution is a recursive function (that is, a function that calls itself). I have tagged the question with "recursion" for that reason.Ryan C. Thompson– Ryan C. Thompson2010-12-07 07:43:16 +00:00Commented Dec 7, 2010 at 7:43
3 Answers
Just a quick answer, not sure about efficiency/elegancy:
(defun reverse-deeply (list)
(mapcar #'(lambda (li)
(cond
((consp li) (reverse-deeply li))
(t li)))
(reverse list)))
1 Comment
Here is a version that works for me in Common-Lisp.
(defun reverse-list (list)
(if (atom list)
list ;; Not actually a list, return the atom
(reverse (mapcar #'reverse-list list)))
;; Testing it out
(reverse-list '((1 2 3) (4 5 (3 6))))
Output:
(((6 3) 5 4) (3 2 1))
Mapcar is a function that takes another function as its first parameter and a list as its second parameter. It then calls that function on each element of the list. It returns a list of all of the answers. So after I use 'mapcar' to reverse all of the sublists, I call 'reverse' again to reverse the bigger list.
The function that it calls on each sublist is 'reverse-list'. This checks if the list is an atom. If it is, then it returns itself. If it's a list, then it calls mapcar again on each element in the list, then reverses the result.
6 Comments
mapcar works, it may be confusing, since there are two ways to achieve the result: a) reverse the top-level container list; b) reverse member-lists :)(reverse (mapcar #'reverse '((1 2 3) (4 5 6)))) isn't obvious?