rog1n Posted January 10, 2022 Share Posted January 10, 2022 Hello, I am trying create a function that replace a item from a list with sublist (like a tree) with a sublist, so at momento I do this: (defun test (lst o n) (if lst (cond ((= (type (car lst)) 'LIST) (list (test (car lst) o n)) ) ((atom (car lst)) (if (equal o (car lst)) (cond ((atom n) (cons n (test (cdr lst) o n))) ((= (type n) 'LIST) (cons n (test (cdr lst) o n))) ) (cons (car lst) (test (cdr lst) o n)) ) ) ) ) ) if I execute with this list: (setq number (list 1 (list 2 (list 3 (list 4 5))))) (test number 5 (list 5 6)) --> result is (1 (2 (3 (4 (5 6))))) work like I need but if I tried with this list: (setq number2 (list 1 (list 2 (list 3 (list 4 5))) 7)) (test number2 5 (list 5 6)) --> result is (1 (2 (3 (4 (5 6))))) dont work, the correct result is: (1 (2 (3 (4 (5 6)))) 7) or (test number2 7 (list 7 8)) --> result is (1 (2 (3 (4 5)))) dont work, the correct result is: (1 (2 (3 (4 5))) (6 7)) If possible, anyone can help me to fix the code? Quote Link to comment Share on other sites More sharing options...
mhupp Posted January 11, 2022 Share Posted January 11, 2022 http://lee-mac.com/substn.html Quote Link to comment Share on other sites More sharing options...
rog1n Posted January 11, 2022 Author Share Posted January 11, 2022 6 minutes ago, mhupp said: http://lee-mac.com/substn.html Thank you for the reply, but unfortunately it doesn't help me, because I dont know the index of the item I want replace. Quote Link to comment Share on other sites More sharing options...
mhupp Posted January 11, 2022 Share Posted January 11, 2022 (edited) https://documentation.help/AutoLISP-Functions/WS1a9193826455f5ff1a32d8d10ebc6b7ccc-689a.htm ;;---------------------=={ Subst Nth }==----------------------;; ;; ;; ;; Substitutes an item at the nth position in a list. ;; ;;------------------------------------------------------------;; ;; Author: Lee Mac, Copyright © 2011 - www.lee-mac.com ;; ;;------------------------------------------------------------;; ;; Arguments: ;; ;; a - item to substitute ;; ;; n - position in list to make the substitution ;; ;; l - list in which to make the substitution ;; ;;------------------------------------------------------------;; ;; Returns: Resultant list following the substitution ;; ;;------------------------------------------------------------;; b - item to be replaced (defun LM:SubstNth ( a b l / i n) (vl-load-com) (setq i -1) (if (setq n (vl-position b l)) (mapcar '(lambda ( x ) (if (= (setq i (1+ i)) n) a x)) l) ) ) (LM:SubstNth 10 4 '(5 4 3 2 1 0)) (5 10 3 2 1 0) Edited January 11, 2022 by mhupp Quote Link to comment Share on other sites More sharing options...
rog1n Posted January 11, 2022 Author Share Posted January 11, 2022 Still nothing work I belive its because I have list inside others list check the example: (setq lst (list 1 (list 2 (list 3 (list 4 5))))) (LM:SubstNth 5 6 lst) -> nil Quote Link to comment Share on other sites More sharing options...
mhupp Posted January 11, 2022 Share Posted January 11, 2022 Any reason your running 3 or 4 levels deep with lists? Quote Link to comment Share on other sites More sharing options...
rog1n Posted January 11, 2022 Author Share Posted January 11, 2022 1 hour ago, mhupp said: Any reason your running 3 or 4 levels deep with lists? I am trying make a scheme with parent and child Do you have a better solution? 1 Quote Link to comment Share on other sites More sharing options...
Steven P Posted January 11, 2022 Share Posted January 11, 2022 I don't know exactly how to explain it.. either I will look brilliant by saying what I think or everyone will say "no it's not that at all you fool". Anyway I think it is all to do with moving along the nested lists until there is no more lists but it can't then 'un-nest' back up the levels.. I think... So what I thought is you might need to explicitly loop through each item in the list and analyse that as you loop through and repeat as you come to a new nested list, when that nested list is finished the loop moves onto the next item in its parent list.. or something like that Anyway, you could try this: (defun testlist (mylist mysearchterm myreplace / Newlist) (defun checklist ( alist mysearchterm myreplace / acount mylist) (defun LM:SubstNth ( a n l ) (if l (if (zerop n) (cons a (cdr l)) (cons (car l) (LM:SubstNth a (1- n) (cdr l))) ) ) ) (setq acount 0) (while (< acount (length alist)) (if (= (TYPE (nth acount alist)) 'LIST) (setq mylist (LM:SubstNth (checklist (nth acount alist) mysearchterm myreplace ) acount alist)) (progn ;;if not list (if ( = (nth acount alist) mysearchterm) (setq mylist (LM:SubstNth myreplace acount alist)) ) ; end if ) ; end progn ) ; end if (setq acount (+ acount 1)) ) ; end while mylist ) (princ "My Old List: ") (princ mylist) (princ ". Subs: ") (princ mysearchterm) (princ ". New Item: ") (princ myreplace) (setq Newlist (checklist mylist mysearchterm myreplace)) (princ " : My New List: ") (princ Newlist) (princ) ) 1 1 Quote Link to comment Share on other sites More sharing options...
rog1n Posted January 12, 2022 Author Share Posted January 12, 2022 47 minutes ago, Steven P said: I don't know exactly how to explain it.. either I will look brilliant by saying what I think or everyone will say "no it's not that at all you fool". Anyway I think it is all to do with moving along the nested lists until there is no more lists but it can't then 'un-nest' back up the levels.. I think... So what I thought is you might need to explicitly loop through each item in the list and analyse that as you loop through and repeat as you come to a new nested list, when that nested list is finished the loop moves onto the next item in its parent list.. or something like that Anyway, you could try this: (defun testlist (mylist mysearchterm myreplace / Newlist) (defun checklist ( alist mysearchterm myreplace / acount mylist) (defun LM:SubstNth ( a n l ) (if l (if (zerop n) (cons a (cdr l)) (cons (car l) (LM:SubstNth a (1- n) (cdr l))) ) ) ) (setq acount 0) (while (< acount (length alist)) (if (= (TYPE (nth acount alist)) 'LIST) (setq mylist (LM:SubstNth (checklist (nth acount alist) mysearchterm myreplace ) acount alist)) (progn ;;if not list (if ( = (nth acount alist) mysearchterm) (setq mylist (LM:SubstNth myreplace acount alist)) ) ; end if ) ; end progn ) ; end if (setq acount (+ acount 1)) ) ; end while mylist ) (princ "My Old List: ") (princ mylist) (princ ". Subs: ") (princ mysearchterm) (princ ". New Item: ") (princ myreplace) (setq Newlist (checklist mylist mysearchterm myreplace)) (princ " : My New List: ") (princ Newlist) (princ) ) I am trying to understand what you do, anyway its working like I need, thank you all for the help! 1 Quote Link to comment Share on other sites More sharing options...
Stefan BMR Posted January 12, 2022 Share Posted January 12, 2022 Hi Here is a simple function, works for any nesting level (defun replace_sublist (lst old new) (mapcar (function (lambda (x) (cond ((equal x old) new) ((atom x) x) (T (replace_sublist x old new)) ) ) ) lst ) ) And some tests _$ (setq number2 (list 1 (list 2 (list 3 (list 4 5))) 7)) (1 (2 (3 (4 5))) 7) _$ (replace_sublist number2 5 (list 5 6)) (1 (2 (3 (4 (5 6)))) 7) _$ (replace_sublist number2 7 (list 7 8)) (1 (2 (3 (4 5))) (7 8)) _$ (replace_sublist number2 (list 4 5) 4) (1 (2 (3 4)) 7) _$ 1 1 Quote Link to comment Share on other sites More sharing options...
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.