Recursing Through Nested List LISP

僤鯓⒐⒋嵵緔 提交于 2020-01-16 21:59:13

问题


How would I recurse through nested lists?

For example, given: '((A 1 2) (B 3 4))

How would I add 2 to the second element in each nested sublist?

(defun get-p0 (points)
    (loop for x from 0 to
            (-  (list-length    points) 1) do
                (+ 2 (cadr (nth x points)))
    )
)

I'm not really sure why (get-p0 '((A 1 2) (B 3 4))) returns NIL.


回答1:


I'd go with something like this:

(loop for (letter x y) in '((A 1 2) (B 3 4))
     collect (list letter (+ 2 x) y))

The reason: it's shorter and you don't measure the length of the list in order to iterate over it (why would you do that?)




回答2:


Since you ask for a recursive solution:

(defun get-p0 (lst &optional (n 0))
  (if (null lst) 
      nil
      (let ((elt1 (first lst)) (eltn (cdr lst)))
        (if (listp elt1)
             (cons (get-p0 elt1) (get-p0 eltn))
             (cons (if (= n 1) (+ elt1 2) elt1) (get-p0 eltn (+ n 1)))))))

so

? (get-p0 '((A 1 2) (B 3 4)))
((A 3 2) (B 5 4))

and it recurses further down if necessary:

? (get-p0 '((A 0 2) ((B -4 4) (C 10 4))))
((A 2 2) ((B -2 4) (C 12 4)))



回答3:


The way you put it, you can consider the problem as a basic recursion pattern: you go through a list using recursion or iteration (mapcar, reduce, etc.; dolist, loop, etc.) and apply a function to its entries. Here is a functional solution:

(defun get-p0 (points)
  (mapcar #'add-2 points))

where the auxiliary function can be defined as follows:

(defun add-2 (lst)
  "Add 2 to the 2nd item"
  (let ((res '()))
    (do ((l lst (cdr l))
         (i 1 (1+ i)))
      ((null l) (nreverse res))
      (push (if (= 2 i)
              (+ 2 (car l))
              (car l))
            res))))



回答4:


As written your 'loop' use does not return anything; thus NIL is returned. As is your code is simply iterating over x and computing something; that something isn't stored anywhere.

So, how to get your desired result? Assuming you are willing to modify each point in points, this should work:

(defun get-p0 (points)
  (loop for x from 0 to (- (list-length points) 1) do
    (let ((point (nth x points)))
      (setf (cadr point) (+ 2 (cadr point)))))
   points)


来源:https://stackoverflow.com/questions/15351988/recursing-through-nested-list-lisp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!