Here is a little puzzle for solving in case of extra free time...
I have nested lists within list...
Assuming that the most nested element is number, I want to apply function to each of these elements,
and returning result of evaluation should be list exactly in the same form as original but with elements changed
according to applied function :
Example :
List : '((((1 3)) (2 4) (((5 7))) (6) ((
) 8 7 6 5 4 3 2 1))
(f (lambda ( x ) (* x 5)) '((((1 3)) (2 4) (((5 7))) (6) ((
) 8 7 6 5 4 3 2 1)) )
=> ((((5 15)) (10 20) (((25 35))) (30) ((40)) 40 35 30 25 20 15 10 5))
I know how to solve this one, but it's to simple :
List : '((1 2) (3 4))
Solution :
(defun f ( func lst )
(mapcar '(lambda ( x ) (mapcar '(lambda ( y ) (func y)) x)) lst)
)
(f (lambda ( x ) (* x 5)) '((1 2) (3 4)) )
=> ((5 10) (15 20))
Ok, I have solution with help of Lee's subfunction :
(defun f ( func lst / LM:Flatten lstf lstfn lsts lstfs lstfns lstfsa lstsn pos )
(defun LM:Flatten ( l )
(if (atom l) (list l)
(append (LM:Flatten (car l)) (if (cdr l) (LM:Flatten (cdr l))))
)
)
(setq lstf (LM:Flatten lst))
(setq lstfn (mapcar 'func lstf))
(setq lsts (vl-prin1-to-string lst))
(setq lstfs (mapcar '(lambda ( x ) (vl-prin1-to-string x)) lstf))
(setq lstfns (mapcar '(lambda ( x ) (vl-prin1-to-string x)) lstfn))
(setq lstfsa (mapcar '(lambda ( a b ) (list a b)) lstfs lstfns))
(setq lstsn lsts)
(setq pos 0)
(foreach el lstfsa
(setq lstsn (vl-string-subst (cadr el) (car el) lstsn pos))
(setq pos (1+ (vl-string-search (cadr el) lstsn pos)))
)
(read lstsn)
)
So far so good :
(f (lambda ( x ) (* x 5)) '((((1 3)) (2 4) (((5 7))) (6) ((
) 8 7 6 5 4 3 2 1)) )
=> ((((5 15)) (10 20) (((25 35))) (30) ((40)) 40 35 30 25 20 15 10 5))
But what if elements are some other type of data instead of numbers (symbols, strings)... I want to keep them unchanged... :
(defun f
( func lst
/ LM:Flatten lstf lstfn lsts lstfs lstfns lstfsa lstsn pos
)
)
)
(setq lstf
(LM:Flatten lst
)) )
)
(f (lambda ( x ) (* x 5)) '((((1 3)) (2 4) (((5 7))) (6) ((
) 8 7 6 5 "A" "B" C D T nil ("E") ('F) 'G "Marko")) )
=> ((((5 15)) (10 20) (((25 35))) (30) ((40)) 40 35 30 25 "A" "B" C D T nil ("E") ((QUOTE F)) (QUOTE G) "Marko"))
I wonder have I missed something, or is there any better way to achieve the same result...
M.R.