TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: TheRubens on June 24, 2019, 03:14:55 AM

Title: How do I update sub-lists in a list (or another sub-lists)
Post by: TheRubens on June 24, 2019, 03:14:55 AM
Hello fellows,

I am looking for a solution to update the sublist in a sublist that in another sublist...
The structure of the list looks like this:

1.
      1.1
            1.1.1
                    1.1.1.1
                    1.1.1.2
                    1.1.1.3
                    ......
            1.1.2
                    1.1.2.1
                    1.1.2.2
                    1.1.2.3
                    ......
            ......

      1.2
            1.2.1
                    1.2.1.1
                    1.2.1.2
                    1.2.1.3
                    ......
            1.2.2
                    1.2.2.1
                    1.2.2.2
                    1.2.2.3
                    ......
            ......

      ......

2.
      2.1
            2.1.1
                   2.1.1.1
                   ......
           ......
      ......
......


This structure may contain more than 4 sub-lists and I want to write a general function,Lets say (defun substADV (list n newitem) ...)
What I want to achieve is if I call (substADV list 2 "test") then all sublist (or item) 1.1, 1.2, ... 2.1, ... 3.1,... and the like will become "test". And if I call (substADV list 3 "test") then all 1.1.1, 1.1.2, ... 1.2.1,... 1.3.1 will be updated to "test".


Can anyone guide me how to write a function to make this work? Thank you very much.








Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: kdub_nz on June 24, 2019, 06:40:30 AM

What would the actual shape of the list you indicate take ??
Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: roy_043 on June 24, 2019, 06:59:46 AM
Maybe this:
Code - Auto/Visual Lisp: [Select]
  1. (setq lst
  2.   '(
  3.     ("1."
  4.       ("1.1"
  5.         ("1.1.1"
  6.           ("1.1.1.1" "1.1.1.2" "1.1.1.3")
  7.         )
  8.         ("1.1.2"
  9.           ("1.1.2.1" "1.1.2.2" "1.1.2.3")
  10.         )
  11.       )
  12.       ("1.2"
  13.         ("1.2.1"
  14.           ("1.2.1.1" "1.2.1.2" "1.2.1.3")
  15.         )
  16.         ("1.2.2"
  17.           ("1.2.2.1" "1.2.2.2" "1.2.2.3")
  18.         )
  19.       )
  20.     )
  21.     ("2."
  22.       ("2.1"
  23.         ("2.1.1"
  24.           ("2.1.1.1")
  25.         )
  26.       )
  27.     )
  28.   )
  29. )
  30.  
  31. ; (substADV lst 2 "test")
  32. (defun substADV (lst n new / N_subst)
  33.  
  34.   (defun N_subst (lst cur)
  35.     (mapcar
  36.       '(lambda (itm)
  37.         (cond
  38.           ((vl-consp itm) (N_subst itm (1+ cur)))
  39.           ((= cur n) new)
  40.           (T itm)
  41.         )
  42.       )
  43.       lst
  44.     )
  45.   )
  46.  
  47.   (N_subst lst 0)
  48.  
  49. )
Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: TheRubens on June 24, 2019, 07:23:37 AM
Thanks for your reply.
The list actually varies. I am seeking a general function that can solve all these kind of lists.

Simply put. The original list is like a multiple level pyramid and I am looking for a function that allows me to update a certain level.

For example, I have a list called LST1 that looks like this:
(list
      (list "Women"
                (list "Jacket"
                                   (list "XS"
                                                 (list "Red" "Yellow" "Blue")
                                   )
                                   (list "S"
                                                 (list "White" "Green" "Blue")
                                   )
                                  ...
                )
               (list "Dress"
                                   (list "XS"
                                                 (list "Cyan" "Yellow")
                                   )
                                   (list "S"
                                                 (list "Black" "Green" "Blue")
                                   )
                                  ...
                )
               ...
      )
      (list "Men"
                (list "Jacket"
                                   (list "S"
                                                 (list "White" "Yellow" "Blue")
                                   )
                                   (list "M"
                                                 (list "White" "Black" "Blue")
                                   )
                                  ...
                )
               (list "Chino"
                                   (list "31"
                                                 (list "Cyan" "Yellow")
                                   )
                                   (list "32"
                                                 (list "Black" "Blue")
                                   )
                                  ...
                )
               ...
)


So if call (substADV LST1 2 "NEW") it will return something like this
(list
      (list "Women"
                "NEW"
                "NEW"
               ...
      )
      (list "Men"
                “NEW"
               "NEW"
               ...
)

The new item "NEW" here is just a simplified way to indicate my idea, I will actually replace them with new corresponding items or lists. I am just seeking for a way to loop this list to see what is the best way to update sub-lists at certain level from a pyramid-like big list.

I hope it makes sense. Thank you.
   




Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: TheRubens on June 24, 2019, 07:29:27 AM
Maybe this:
Code - Auto/Visual Lisp: [Select]
  1. (setq lst
  2.   '(
  3.     ("1."
  4.       ("1.1"
  5.         ("1.1.1"
  6.           ("1.1.1.1" "1.1.1.2" "1.1.1.3")
  7.         )
  8.         ("1.1.2"
  9.           ("1.1.2.1" "1.1.2.2" "1.1.2.3")
  10.         )
  11.       )
  12.       ("1.2"
  13.         ("1.2.1"
  14.           ("1.2.1.1" "1.2.1.2" "1.2.1.3")
  15.         )
  16.         ("1.2.2"
  17.           ("1.2.2.1" "1.2.2.2" "1.2.2.3")
  18.         )
  19.       )
  20.     )
  21.     ("2."
  22.       ("2.1"
  23.         ("2.1.1"
  24.           ("2.1.1.1")
  25.         )
  26.       )
  27.     )
  28.   )
  29. )
  30.  
  31. ; (substADV lst 2 "test")
  32. (defun substADV (lst n new / N_subst)
  33.  
  34.   (defun N_subst (lst cur)
  35.     (mapcar
  36.       '(lambda (itm)
  37.         (cond
  38.           ((vl-consp itm) (N_subst itm (1+ cur)))
  39.           ((= cur n) new)
  40.           (T itm)
  41.         )
  42.       )
  43.       lst
  44.     )
  45.   )
  46.  
  47.   (N_subst lst 0)
  48.  
  49. )

Thanks roy_043, I will have a look when I am home to see if this is what I am after. Again, Thank you.
Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: roy_043 on June 24, 2019, 08:08:12 AM
Hmm, after re-reading I think you probably want this:
Code - Auto/Visual Lisp: [Select]
  1. (defun substADV-Alt (lst n new / N_subst)
  2.  
  3.   (defun N_subst (lst cur)
  4.     (mapcar
  5.       '(lambda (itm)
  6.         (cond
  7.           ((= cur n) new)
  8.           ((vl-consp itm) (N_subst itm (1+ cur)))
  9.           (T itm)
  10.         )
  11.       )
  12.       lst
  13.     )
  14.   )
  15.  
  16.   (N_subst lst 0)
  17.  
  18. )

Edit:
Actually the examples are confusing. In the first post it would seem that atoms and sublists at the same nesting level n should all be replaced. The substADV-Alt function will do this. But its results do not match the OP's last post.
Code: [Select]
(setq lst1
  (list
    (list "Women"
      (list "Jacket"
        (list "XS"
          (list "Red" "Yellow" "Blue")
        )
        (list "S"
          (list "White" "Green" "Blue")
        )
      )
      (list "Dress"
        (list "XS"
          (list "Cyan" "Yellow")
        )
        (list "S"
          (list "Black" "Green" "Blue")
        )
      )
    )
    (list "Men"
      (list "Jacket"
        (list "S"
          (list "White" "Yellow" "Blue")
        )
        (list "M"
          (list "White" "Black" "Blue")
        )
      )
      (list "Chino"
        (list "31"
          (list "Cyan" "Yellow")
        )
        (list "32"
          (list "Black" "Blue")
        )
      )
    )
  )
)

(substADV-Alt lst1 2 "NEW") => (("Women" ("NEW" "NEW" "NEW") ("NEW" "NEW" "NEW")) ("Men" ("NEW" "NEW" "NEW") ("NEW" "NEW" "NEW")))




Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: roy_043 on June 24, 2019, 09:06:33 AM
This?:
Code - Auto/Visual Lisp: [Select]
  1. ; (substADV-Alt2 lst1 1 "NEW") => (("Women" "NEW" "NEW") ("Men" "NEW" "NEW"))
  2. (defun substADV-Alt2 (lst n new / N_subst)
  3.  
  4.   (defun N_subst (lst cur)
  5.     (mapcar
  6.       '(lambda (itm)
  7.         (cond
  8.           ((not (vl-consp itm)) itm)
  9.           ((= cur n) new)
  10.           (T (N_subst itm (1+ cur)))
  11.         )
  12.       )
  13.       lst
  14.     )
  15.   )
  16.  
  17.   (N_subst lst 0)
  18.  
  19. )
Title: Re: How do I update sub-lists in a list (or another sub-lists)
Post by: TheRubens on June 26, 2019, 10:55:15 PM
Hmm, after re-reading I think you probably want this:
Code - Auto/Visual Lisp: [Select]
  1. (defun substADV-Alt (lst n new / N_subst)
  2.  
  3.   (defun N_subst (lst cur)
  4.     (mapcar
  5.       '(lambda (itm)
  6.         (cond
  7.           ((= cur n) new)
  8.           ((vl-consp itm) (N_subst itm (1+ cur)))
  9.           (T itm)
  10.         )
  11.       )
  12.       lst
  13.     )
  14.   )
  15.  
  16.   (N_subst lst 0)
  17.  
  18. )

Edit:
Actually the examples are confusing. In the first post it would seem that atoms and sublists at the same nesting level n should all be replaced. The substADV-Alt function will do this. But its results do not match the OP's last post.
Code: [Select]
(setq lst1
  (list
    (list "Women"
      (list "Jacket"
        (list "XS"
          (list "Red" "Yellow" "Blue")
        )
        (list "S"
          (list "White" "Green" "Blue")
        )
      )
      (list "Dress"
        (list "XS"
          (list "Cyan" "Yellow")
        )
        (list "S"
          (list "Black" "Green" "Blue")
        )
      )
    )
    (list "Men"
      (list "Jacket"
        (list "S"
          (list "White" "Yellow" "Blue")
        )
        (list "M"
          (list "White" "Black" "Blue")
        )
      )
      (list "Chino"
        (list "31"
          (list "Cyan" "Yellow")
        )
        (list "32"
          (list "Black" "Blue")
        )
      )
    )
  )
)

(substADV-Alt lst1 2 "NEW") => (("Women" ("NEW" "NEW" "NEW") ("NEW" "NEW" "NEW")) ("Men" ("NEW" "NEW" "NEW") ("NEW" "NEW" "NEW")))


Hi Roy, Sorry for the confusion. The newitem "NEW" is just indicative only to make my question easier to understand. the new items can be any kind. it can be a string or list. I want to replace all sublists at the same target level with the new items. So in the first example, if I do (substADV lst 2 "NEW") all the list at level 2 (1.1 1.2 ... 2.1, 2.1..) will be replaced with newitem "NEW". as items 1.1.1, 1.1.1.1 and the like are part of item 1.1 so they won't exist anymore. so the expected result will be (list (list 1 (list "NEW" "NEW" ...)) (list 2 (list "NEW" "NEW" ...)) ...). I hope it makes sense.
You last script seems fine. I will have a test and let you know. Thank you very much. :)