user2296277
user2296277

Reputation: 25

Iterate through every item in the list using LISP

Given I have the list that might vary in its' structure- it might have multiple lists within list, how do I iterate through every element? Example of the list: (or (and (not a) (not b)) (or (and x) t)))

Upvotes: 1

Views: 2041

Answers (3)

Sylwester
Sylwester

Reputation: 48775

From SICP I remember accumulate-tree which can be considered a reduce for trees. In CL it might look like this:

(defun accumulate-tree (tree term combiner null-value)
  (labels ((rec (tree)
             (cond ((null tree) null-value)
                   ((atom tree) (funcall term tree))
                   (t (funcall combiner (rec (car tree)) 
                                        (rec (cdr tree)))))))
    (rec tree)))

You can do stuff like adding all numbers in the tree:

(defparameter *value-tree* '(1 2 (3 4 (5 6)) 3))
(accumulate-tree *value-tree*
                 (lambda (x) (if (numberp x) x 0))
                 #'+
                 0) ; => 24

To implement @coredumps map-tree you use cons as combiner and nil ass nil value:

(defun map-tree (function tree)
  (accumulate-tree tree function #'cons nil))

Upvotes: 0

sheikh_anton
sheikh_anton

Reputation: 3452

It's a tipical situation for maptree function.

(defun maptree (fn tree)
  (cond
    ((null tree) tree)
    ((atom tree) (funcall fn tree))
    (t (cons
         (maptree fn (first tree))
         (maptree fn (rest tree))))))

So you can do (maptree #'what-to-do your-list).

I will just print all elements, you can provide any function you want, it'll b executed on each element of your tree.

CL-USER> (let ((lis 
                 '(or (and (not a) (not b)) (or (and x) t))))
           (maptree #'print lis)) 

OR 
AND 
NOT 
A 
NOT 
B 
OR 
AND 
X 
T 

Upvotes: 3

Leo
Leo

Reputation: 1934

This is a good case for a recursive function. You probably want something like this:

(defun iterate (l) (if (atom l) (do-something-with l) (mapcar #'iterate l)))

The function do-something-with obviously defines what you want to do with each element. Further, the mapcar could be replaced by another mapping function, depending on whether you want to accumulate the results of do-something-with or not.

Upvotes: 0

Related Questions