Author Topic: How to substitute some item in different depth list  (Read 6137 times)

0 Members and 1 Guest are viewing this topic.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
How to substitute some item in different depth list
« on: June 29, 2006, 09:15:24 PM »
How to substitute some item in different depth list

In Lisp, the list is very useful, it is more  flexible  than the ordinary array in other Language such as

Fortran or Basic.
But when I translate some other Language to Lisp, I am always confuse of how to deal with the

translation between array and list.
For example,

A=[ x y z ....]
B=[[a1 b1 c1][a2 b2 c2][.........]]
C=[ [[x1 y1 z1][x2 y2 z2]] [[x3 y3 z3][x4 y4 z4]] [...]]

In other Language, we often get the value of a array by:
Value=A[5] or B[6,5] or C[3,4,5]

or put the value by:
 A[5] or B[6,5] or C[3,4,5]=Value

but in Lisp, I found it is not so easy
when get a value is easlier, we should use (nth (nth (nth ))),
but when put a value, it is trouble, maybe we can write a function, such as SUBSTI(new position

list) to substitute, but when the list is multi-depth, such as B or C or more deep list. Maybe we

should write several defun to adapt the different situation.

Because many scientific code are written by other Language, sometimes I need to translate it to

Lisp, for example, inverse matrix,  I am not familar with safearray in vlisp and hope it could be

done by Lisp.
so my question is: How can we write a more general function to substitute the item in the list

with multi-depth, no matter how deep the list is.
For example, we can
PUT(C, 1,2,3, z2a) to substitute the z2 in C
PUT(B, 2,2,b2a) to substitute the b2 to b2a in B

GET(B, 2,2) to get the value of b2, and GET(A,3) to get the value of z

Maybe I get a wrong way of the problem, Maybe it is easy, but I hope you could help me.
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to substitute some item in different depth list
« Reply #1 on: June 29, 2006, 10:42:41 PM »
not the most elegant or efficient, but ..
Have a look at nth

Code: [Select]

(SETQ b (LIST (LIST 1 2 3) (LIST 4 5 6) (LIST 7 8 9)))

;;=> ((1 2 3) (4 5 6) (7 8 9))

;;; note .. nth is zero based ....
(SETQ index 2
      step 1
)


(SETQ xx (NTH step (NTH index b)))

;; => returns 8
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #2 on: June 29, 2006, 11:47:39 PM »
thanks kerry

nth is the way to read the list, I define the following code to read the depth=2 list's element, but when the depth is larger than 2, the function have to be rewrote, so I hope a better way to deal it. especially the put value function.

Code: [Select]
(defun [n,m] (a n m / i)      
 (setq i (nth (1- m) (nth (1- n) a)))
  i
)

(SETQ b (LIST (LIST 1 2 3) (LIST 4 5 6) (LIST 7 8 9)))
-----> b  ((1 2 3) (4 5 6) (7 8 9))
([n,m] b 3 2)
----->8
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How to substitute some item in different depth list
« Reply #3 on: June 30, 2006, 01:09:56 AM »
Here is my take on the problem.
Code: [Select]
(defun c:test ()
  ;;   array structure
  ;;  (list z0(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;        z1(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;        z2(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;  )

  (setq array '((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
                (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d"))
                (("e" "f" "g" "h") ("i" "j" "k" "l") ("m" "n" "o" "p") ("q" "r" "s" "t"))
               )
  )

  (setq x 3
        y 1
        z 2
  )
  (print (setq target (get_itm x y z array)))

  (setq array (substu_array "XX" x y z array))
  (print array)
  (princ)
)


Code: [Select]
(defun get_itm (x y z array)
  (nth x (nth y (nth z array)))
)


Code: [Select]
(defun substu_array (newitm x y z array)
  (subst
    (subst
      (subst newitm (nth x (nth y (nth z array))) (nth y (nth z array)))
      (nth y (nth z array))
      (nth z array)
    )
    (nth z array)
    array
  )
)

Good night all :)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #4 on: June 30, 2006, 04:26:05 AM »
Thank you, CAB, good code.

It seems that subst is substitute- olditem to newitem, so when the element is duplicate, it get wrong.

(setq array '((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
                (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d"))
                (("e" "f" "g" "h") ("l" "j" "k" "l") ("m" "n" "o" "p") ("q" "r" "s" "t"))
               )
  )

after test, it become:
((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
(("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d")) (("e"
"f" "g" "h") ("XX" "j" "k" "XX") ("m" "n" "o" "p") ("q" "r" "s" "t")))


I have wrote a function, it deal with the 2 dimension change, but just like your code, When the array depth of the array is different, the function will be rewrite,
Is it possible to define a function about

FUNC( list_to_be_change, newvalue, position_list)
The position_list is a list that in change one
such as (7) for one dimension array, (3,4) for two dimension array, (3,4,5,6,7,8) for n dimension array

so, when the depth of the array change, the function can be also use.

I think maybe repeat or foreach should be use, but still in confuse. I didnt think it through yet.

my code, reference stdlib
Code: [Select]
;;;test function
(defun c:test()
(setq array '((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
                (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d"))
                (("e" "f" "g" "h") ("e" "f" "g" "h") ("m" "n" "o" "p") ("q" "r" "s" "t"))
               )
)
(setq array (qj-setnmth '("l" "j" "k" "XX") 3 2 array))
)


;The stdlib function
(defun std-%setnth (new i lst / fst len)
  (cond
    ((minusp i)
      lst
    )
    ((> i (setq len (length lst)))
      lst
    )
    ((> i (/ len 2))
      (reverse (std-%setnth new (1- (- len i)) (reverse lst)))
    )
    (t
      (append
(progn
  (setq fst nil)        ; ; possible vl lsa compiler bug
  (repeat (rem i 4)
    (setq fst (cons (car lst) fst)
  lst (cdr lst)
    )
  )
  (repeat (/ i 4)
    (setq fst (cons (cadddr lst) (cons (caddr lst) (cons
(cadr lst)
(cons
       (car lst)
       fst
)
   )
)
      )
  lst (cddddr lst)
    )
  )
  (reverse fst)
)
(if (listp new)
  new
  (list new)
)        ; v0.4001
(cdr lst)
      )
    )
  )
)
(defun std-setnth (new i lst)
  (std-%setnth (list new) i lst)
)


;;;substitute the 2 dimension list's i and j element(i and j start from 1)
(defun qj-setnmth (new i j lst / listb lista)
  (setq listb lst)
  (setq i (1- i))
  (setq j (1- j))
  (setq lista (nth i lst))
  (setq lista (std-setnth new j lista))
  (setq listb (std-setnth lista i listb))
  listb
)


((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L"
"M" "N")) (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c"
"d")) (("e" "f" "g" "h") ("l" "j" "k" "XX") ("m" "n" "o" "p") ("q" "r" "s"
"t")))

« Last Edit: June 30, 2006, 04:49:45 AM by yuanqiu »
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How to substitute some item in different depth list
« Reply #5 on: June 30, 2006, 08:20:17 AM »
OK, this may be the solution to that issue.
Code: [Select]
(defun c:test ()
  ;;   array structure
  ;;  (list z0(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;        z1(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;        z2(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;  )

  (setq array '((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
                (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d"))
                (("e" "f" "g" "h") ("8" "j" "k" "8") ("m" "n" "o" "p") ("q" "r" "s" "t"))
               )
  )

  (setq x 3
        y 1
        z 2
  )
  (print (setq target (get_itm x y z array)))

  (setq array (substu_array "XX" x y z array))
  (print array)
  (princ)
)


Code: [Select]
(defun get_itm (x y z array)
  (nth x (nth y (nth z array)))
)


Code: [Select]
(defun substu_array (newitm x y z array)
  (insert@1 array (insert@1 (nth z array) (insert@1 (nth y (nth z array)) newitm x) y) z)
)


Code: [Select]
;; by  CAB 07/30/2004
(defun insert@1 (lst itm pos / nlst idx)
  (setq nlst '()
        idx -1)
  (while (< (setq idx (1+ idx)) (length lst))
    (if (= idx pos)
      (setq nlst (cons itm nlst))
      (setq nlst (cons (nth idx lst) nlst))
    )
  )
  (reverse nlst)
)
« Last Edit: June 30, 2006, 08:24:50 AM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #6 on: June 30, 2006, 09:21:45 PM »
hi,CAB
Your inser@ is rather good, I worte a substu_array1, and now the position could be a list, then it can adapt many depth, thank you for your inspiration.
Code: [Select]
;; by  CAB 07/30/2004
(defun insert@1 (lst itm pos / nlst idx)
  (setq nlst '()
idx -1
  )
  (while (< (setq idx (1+ idx))
    (length lst)
)
    (if (= idx pos)
      (setq nlst (cons itm nlst))
      (setq nlst (cons (nth idx lst) nlst))
    )
  )
  (reverse nlst)
)
(defun get_itm (x y z array)
  (nth x (nth y (nth z array)))
)
;by QJCHEN 2006/07/01, to substitute the newitm to the lis='(i j k l) of array
(defun substu_array1 (newitm lis array / i array2 array1 lis1)
  (setq i 0
array2 (list array)
array1 array
  )
  (setq lis1 (reverse lis))
  (repeat (length lis)
    (setq array1 (nth (nth i lis1) array1))
    (setq array2 (append
   array2
   (list array1)
)
    )
    (setq i (1+ i))
  )
  (setq array2 (insert@1 (reverse array2) newitm 0))
  (setq i 1)
  (repeat (1- (length array2))
    (setq array2 (insert@1 array2 (insert@1 (nth i array2) (nth (1- i)
array2
   ) (nth
  (1- i) lis
     )
  ) i
)
    )
    (setq i (1+ i))
  )
  (last array2)
)

;;;;test program
(defun c:test ()
  (setq array '((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
                (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d"))
                (("e" "f" "g" "h") ("8" "j" "k" "8") ("m" "n" "o" "p") ("q" "r" "s" "t"))
               )
  )
  (setq x 3
y 1
z 2
  )
  (print (setq target (get_itm x y z array)))
  (setq temp (substu_array1 "XX" (list x y z) array))
(princ "\n            temp = ") (princ temp);Erase_DV
(getstring "\nPress Enter to continue...");Erase_DV
  (setq temp1 (substu_array1 "XX" (list y z) array))
(princ "\n           temp1 = ") (princ temp1);Erase_DV
(getstring "\nPress Enter to continue...");Erase_DV
  (setq temp2 (substu_array1 "XX" (list z) array))
(princ "\n           temp2 = ") (princ temp2);Erase_DV
(getstring "\nPress Enter to continue...");Erase_DV
  (princ)
)
temp = (((1 2 A B) (C D E F) (G H I J) (K L M N)) ((O P Q R) (S T U
V) (W X Y Z) (a b c d)) ((e f g h) (8 j k XX) (m n o p) (q r s t)))
Press Enter to continue...
           temp1 = (((1 2 A B) (C D E F) (G H I J) (K L M N)) ((O P Q R) (S T U
V) (W X Y Z) (a b c d)) ((e f g h) XX (m n o p) (q r s t)))
Press Enter to continue...
           temp2 = (((1 2 A B) (C D E F) (G H I J) (K L M N)) ((O P Q R) (S T U
V) (W X Y Z) (a b c d)) XX)


But my subrountine is tedious,
If lis=[x y z]
it use array2 to get the (Allarray (nth z allarray) (nth y (nth z allarray)).......)
reverse it
then use repeat to substitute first to second, second to three.
If the array is big one, it will consume large memory.

If there any good ideal, maybe it could use recursion, just like the N! define, but I know little about it.

Thank you:)
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How to substitute some item in different depth list
« Reply #7 on: July 01, 2006, 12:55:00 AM »
OK, one more time . :)
Code: [Select]
(defun c:test ()
  ;;   array structure
  ;;  (list z0(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;        z1(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;        z2(list y0(list x0 x1 x2 x3) y1(list x0 x1 x2 x3) y2(list x0 x1 x2 x3) y3(list x0 x1 x2 x3))
  ;;  )

  (setq array '((("1" "2" "A" "B") ("C" "D" "E" "F") ("G" "H" "I" "J") ("K" "L" "M" "N"))
                (("O" "P" "Q" "R") ("S" "T" "U" "V") ("W" "X" "Y" "Z") ("a" "b" "c" "d"))
                (("e" "f" "g" "h") ("8" "j" "k" "8") ("m" "n" "o" "p") ("q" "r" "s" "t"))
               )
  )

  (setq x 3
        y 1
        z 2
  )
  (setq target (get_itm x y z array))

  (princ "\nx y z  ->")
  (print (substu_array "XX" (reverse (list x y z)) array))
  (princ "\n\ny z  ->")
  (print (substu_array "XX" (reverse (list y z)) array))
  (princ "\n\nz  ->")
  (print (substu_array "XX" (reverse (list z)) array))
  (princ)
)


(defun get_itm (x y z array)
  (nth x (nth y (nth z array)))
)


(defun substu_array (newitm idx lst)
  (if (> (length idx) 1)
    (insert@  lst (substu_array newitm (cdr idx) (nth (car idx) lst)) (car idx))
    (insert@ lst newitm (car idx))
  ) 
)


;; by  CAB 07/30/2004
(defun insert@ (lst itm pos / nlst idx)
  (setq idx -1)
  (while (< (setq idx (1+ idx)) (length lst))
    (if (= idx pos)
      (setq nlst (cons itm nlst))
      (setq nlst (cons (nth idx lst) nlst))
    )
  )
  (reverse nlst)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #8 on: July 02, 2006, 03:32:36 AM »
CAB, Thank you very much, the recursion is so wonderful.
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Sdoman

  • Guest
Re: How to substitute some item in different depth list
« Reply #10 on: July 02, 2006, 06:36:33 PM »
I just wrote the functions below and they seem to work ok.  GetElement and PutElement can be used to Get and Put an element in a list.  The list can be of any size and be nested any way you want, except the list can not contain dotted pairs.

Please read the comments on how to run.  I've included all the error checking I could think of.  But being new, there may be bugs that I had not noticed.  Let me know if do find a bug.

Side note:

In AutoLISP we typicaly design our data into Association list in order to make use of the native functions Assoc, Subst, and Setq.  The Car of an Association list should be a unique key making it easy to find a particular group of data. 

In AutoLISP, unlike other computer languages, we cannot directly write to a particular indexed location in a list.  Rather we must copy the list and modify that copy, substituting the new value for the old value, and eventually saving the modified copy back to the symbol from which the list is bound.

With Vlisp we have safe-arrays, which look very promising, but I really don't have much experience with.

Anyhow, here is my first try...

Code: [Select]
(defun GetElement (Lst Index / Get *rslt*)
  ;; sdoman 7/2/2006
  ;;
  ;; Retuns the element located at a specified
  ;; index position found in the provided list.
  ;; Returns nil on failure.
  ;;
  ;; Arguments:
  ;;
  ;; Lst = a list of elements to search.
  ;;       does not work with dotted pairs.
  ;;
  ;; Index = a list indicating the element location.
  ;;         Zero based: 1st element index is 0, 2nd
  ;;         element index is 1, and so on.
  ;;
  ;; Example:
  ;;
  ;; (setq lst '((1 2 3)(4 (("x" "y" "z")(10.0 20.0 30.0)) 6)))
  ;; (GetElement lst '(1 1 0 2)) -> "z"
  ;; (GetElement lst '(99)) -> nil
  ;;
  (defun Get (aLst iLst / n)
    (if (< -1 (setq n (car iLst)) (length aLst))
      (while (null *rslt*)
        (if (cdr iLst)
          (Get (nth n aLst) (cdr iLst))
          (setq *rslt* (nth n aLst))
        )
      )
      (quit)
    )
  ) ;_
  (if (vl-catch-all-error-p
        (vl-catch-all-apply 'Get (list Lst Index))
      )
    nil
    *rslt*
  )
)

(defun PutElement (Lst Index Value / Put rslt)
  ;; sdoman 7/2/2006
  ;;
  ;; Puts the value at the specified index position
  ;; in the provided list. Returns nil on failure.
  ;;
  ;; Arguments:
  ;;
  ;; Lst = any list not containing dotted pairs.
  ;;
  ;; Index = a list indicating the element location.
  ;;         Zero based: 1st element index is 0, 2nd
  ;;         element index is 1, and so on.
  ;;
  ;; Value = the value to put at index position
  ;;
  ;; Example:
  ;; (setq lst '((1 2 3)(4 (("x" "y" "z")(10.0 20.0 30.0)) 6)))
  ;; (PutElement lst '(1 1 0 2) "TEST")
  ;; -> ((1 2 3) (4 (("x" "y" "TEST") (10.0 20.0 30.0)) 6))
  ;; (PutElement lst '(99) "TEST") -> nil
  ;;
  (defun Put (aLst iLst Val / i n)
    (if (< (setq i -1) (setq n (car iLst)) (length aLst))
      (mapcar '(lambda (x)
                 (setq i (1+ i))
                 (if (= i n)
                   (if (cdr iLst)
                     (Put x (cdr iLst) Val)
                     Val
                   )
                   x
                 )
               )
              aLst
      )
      (quit)
    )
  ) ;_
  (if (vl-catch-all-error-p
        (setq rslt (vl-catch-all-apply 'Put (list Lst Index Value)))
      )
    nil
    rslt
  )
)



qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #11 on: July 02, 2006, 08:39:51 PM »
Thank you 'steved, another good recursion.
Then, could we say Lisp is low efficiency in substitute element? or it forget to give use such function? or the other Language also use recursion to define the  substitute element function? or the data structure of the LIST and ARRAY are different that lead to this question?
But I am just confused, all the way, I love Lisp very much, it give me so much happy.
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How to substitute some item in different depth list
« Reply #12 on: July 03, 2006, 06:00:13 AM »
My variant...  :-)

For any list not containing dotted pairs

Code: [Select]
(defun GetElement-1 (lst Index)
 ;(setq lst '((1 2 3)(4 (("x" "y" "z")(10.0 20.0 30.0)) 6)) Index '(1 1 0 2))
 ;(GetElement-1 lst Index) ->> "z"
 ;(setq lst '((1 2 3)(4 (("x" "y" "z")(10.0 20.0 30.0)) 6)) Index '(99 1 0 2))
 ;(GetElement-1 lst Index) ->> nil
 (if lst
  (if index (GetElement-1 (nth (car Index) lst) (cdr Index)) lst)
 ) ;_  if
) ;_  defun

For any list with dot pairs or without...

Code: [Select]
(defun GetElement-2 (lst Index)
 ;(setq lst '((1 2 3)(4 (("x" "y" . "z")(10.0 20.0 30.0)) 6)) Index '(1 1 0 2))
 ;(GetElement-2 lst Index) ->> "z"
 ;(setq lst '((1 2 3)(4 (("x" "y" "z")(10.0 20.0 30.0)) 6)) Index '(1 1 0 2))
 ;(GetElement-2 lst Index) ->> "z"
 ;(setq lst '((1 2 3)(4 (("x" "y" "z")(10.0 20.0 30.0)) 6)) Index '(99 1 0 2))
 ;(GetElement-2 lst Index) ->> nil
 (if lst
  (if (zerop (car index))
   (if (cdr index)
    (GetElement-2
     (if (listp (car lst))
      (car lst)
     ) ;_  if
     (cdr index)
    ) ;_  GetElement-2
    (car lst)
   ) ;_  if
   (GetElement-2
    (if (atom (cdr lst))
     (list (cdr lst))
     (cdr lst)
    ) ;_  if
    (cons (1- (car index)) (cdr index))
   ) ;_  GetElement-2
  ) ;_  if
 ) ;_  if
) ;_  defun


 Insert of an element in the specified position
 If the position is absent - the program changes structure in the list up
 to specified and we inserts an element.
 For any list with dot pairs or without...

Code: [Select]
(defun PutElement-1 (Lst Index Value)
 ; Insert of an element in the specified position
 ; if the position is absent - we change structure of the list up
 ; to the specified position and we insert an element.
 ; lst = Any list with dot pairs or without...
 ;(PutElement-1 '(1 (2) 2 3) '(1 0) "z") ->> (1 ("z") 2 3)
 ;(PutElement-1 '(1 (2) 2 3) '(0 2 1) "z") ->> ((nil nil (nil "z")) (2) 2 3)
 ;(PutElement-1 '(1 (1 . 2) 2 3) '(1 0) "z") ->> (1 ("z" . 2) 2 3)
 ;(PutElement-1 '(1 (1 . 2) 2 3) '(1 1) "z") ->> (1 (1 "z") 2 3)
 ;(PutElement-1 '(1 (1 . 2) 2 3) '(6 1) "z") ->> (1 (1 . 2) 2 3 nil nil (nil "z"))
 (if (zerop (car index))
  (cons
   (if (cdr index)
    (PutElement-1
     (if (listp (car lst))
      (car lst)
     ) ;_  if
     (cdr index)
     value
    ) ;_  PutElement-1
    Value
   ) ;_  if
   (cdr lst)
  ) ;_  cons
  (cons
   (if (car lst)
    (car lst)
   ) ;_  if
   (PutElement-1
    (if (atom (cdr lst))
     (list (cdr lst))
     (cdr lst)
    ) ;_  if
    (cons (1- (car index)) (cdr index))
    value
   ) ;_  PutElement-1
  ) ;_  cons
 ) ;_  if
) ;_  defun

Sdoman

  • Guest
Re: How to substitute some item in different depth list
« Reply #13 on: July 03, 2006, 08:58:38 PM »
Nice work Evgeniy.   I see that you are a master at recursion.   It is always interesting to see different solutions.  : )

Thank you 'steved, another good recursion.
Then, could we say Lisp is low efficiency in substitute element? or it forget to give use such function? or the other Language also use recursion to define the  substitute element function? or the data structure of the LIST and ARRAY are different that lead to this question?
But I am just confused, all the way, I love Lisp very much, it give me so much happy.

Yuanqiu,

An advantage with lists, as you pointed out in your original post, is that they are more flexible then formal arrays.  With lists we can include mixed types of data, and nest list, inside of list, if that suits the situation.

With arrays on the other hand, we must fill with data of like type, and declare the upper and lower bounds.

In the situation you stated in your originally post, where you want to emulate an algorithm written in another programming language, then I agree that it makes perfect sense to structure your data as a formal array. 

So you have motivated me to experiment with safe-arrays.  I followed the help files and safe-arrays seem easy, and may suite your needs quite well.

Code: [Select]
;;
;; Create a list which we will put into the array later.
;;
(setq lst
  (list (list 100 101 102 103 104 105)
        (list 200 201 202 203 204 205)
        (list 300 301 302 303 304 305)
  )
)
;;
;; Define a zero based array for integer data
;; Note how the array dimensions are determined
;;
(setq array
  (vlax-make-safearray
    vlax-vbInteger
    (cons 0 (1- (length lst)))
    (cons 0 (1- (apply 'max (mapcar 'length lst))))
  )
)
-> #<safearray...>

;;
;; Now let's look at the array,  it's initialized with zeros
;;
(vlax-safearray->list array)
-> ((0 0 0 0 0 0) (0 0 0 0 0 0) (0 0 0 0 0 0))

;;
;; Fill the array with the list we made earlier
;;
(vlax-safearray-fill array lst)
-> #<safearray...>

;;
;; Look at the array now
;;
(vlax-safearray->list array)
-> ((100 101 102 103 104 105)
 (200 201 202 203 204 205)
 (300 301 302 303 304 305))

;;
;; Get an element from the array
;;
(vlax-safearray-get-element array 1 3)
-> 203

;; That was too easy. 

;;
;; How about Putting an element?
;;
(vlax-safearray-put-element array 1 3 999)
-> 999

;; Look at the array one last time

(vlax-safearray->list array)
-> ((100 101 102 103 104 105)
 (200 201 202 999 204 205)
 (300 301 302 303 304 305))

;; Coolness : )
;; makes me happy


{fixed typo}
« Last Edit: July 03, 2006, 09:20:49 PM by 'steved »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How to substitute some item in different depth list
« Reply #14 on: July 04, 2006, 12:40:03 AM »
Nice work Evgeniy.   I see that you are a master at recursion.   It is always interesting to see different solutions.  : )

Yes, I love recursions and often them apply.  :-)
Lisp - recursive language and recursions - its basis!
By means of recursion, it is easy to write short programs - there are no superfluous variables and work fast...

The excellent idea - to use the safe array! :-)

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #15 on: July 04, 2006, 08:46:01 PM »
Thank you all. I will try my best to learn recursion. It is said that it is useful for "fractal" in math.
I was told that recursion is the basic of Lisp, according to 7 basic function, it define almost all the other function, Many basic functions are defined by recursion, I wonder whether AutoLisp can use this basic function, like atom, car ... to define all the function which big Lisp, such as Common Lisp own.
But when I learn Lisp, the "let" "dotime" always make me confuse, can they be define by the basic AutoLisp function.
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How to substitute some item in different depth list
« Reply #16 on: July 05, 2006, 01:31:53 AM »

I will try my best to learn recursion.


Some time back, I have started to write lessons about recursive functions...
" Lessons of the creation of the recursive functions "
 Has published ten lessons!  :-)

The original (RU):
http://www.autocad.ru/cgi-bin/f1/board.cgi?t=25113OT

Machine translation (EN):

http://babelfish.altavista.com/babelfish/trurl_pagecontent?lp=ru_en&trurl=http%3a%2f%2fwww.autocad.ru%2fcgi-bin%2ff1%2fboard.cgi%3ft%3d25113OT
« Last Edit: July 05, 2006, 01:47:24 AM by ElpanovEvgeniy »

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: How to substitute some item in different depth list
« Reply #17 on: July 05, 2006, 05:27:52 AM »
Thanks, I am reading the nice Lesson.
babelfish is a good website, the translation quality is rather good.
but when I reading page 41-60, the transltation get wrong, I dont know why, does any translation site can do it, it seems that google translation cant do it.
OK, I get it
http://www.online-translator.com/url/tran_url.asp?lang=en&url=http%3A%2F%2Fwww.autocad.ru%2Fcgi-bin%2Ff1%2Fboard.cgi%3Ft%3D25113OT%26page%3D3&direction=re&template=General&cp1=NO&cp2=NO&autotranslate=on&psubmit2.x=27&psubmit2.y=15


and I remind the pages which concern about the "Fractall" use autoLisp

http://www.abbs.com.cn/bbs/post/view?sty=1&bid=31&id=589600
« Last Edit: July 06, 2006, 05:43:34 AM by yuanqiu »
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How to substitute some item in different depth list
« Reply #18 on: July 05, 2006, 08:39:07 AM »
Evgeniy
Thanks for sharing your good work. :-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How to substitute some item in different depth list
« Reply #19 on: July 05, 2006, 08:48:48 AM »
Evgeniy
Thanks for sharing your good work. :-)

I badly know the English tongue...  :-(
Otherwise I would translate lessons and have published on theswamp.org!  :-)