前辈的一些讨论
Ref: http://autocad.xarch.at/stdlib/archive/10/msg00054.html - ;;; by Randy Richardson
- (defun subst1 (index new lst / counter lst1)
- (setq counter 0)
- (repeat index
- (setq lst1 (cons (nth counter lst) lst1))
- (setq counter (1+ counter))
- )
- (setq lst1 (cons new lst1))
- (setq counter (1+ counter))
- (repeat (- (length lst) (length lst1))
- (setq lst1 (cons (nth counter lst) lst1))
- (setq counter (1+ counter))
- )
- (reverse lst1)
- )
- ;;; by Frank Oquendo
- (defun replace-element (index newelement lst / tmp)
- (repeat index
- (setq tmp (cons (car lst) tmp)
- lst (cdr lst)
- )
- )
- (append (reverse tmp) (list newelement) (cdr lst))
- )
- ;;; by Tony Tanzillo
- (defun SetNth (index newitem lst / i)
- (setq i -1)
- (mapcar
- '(lambda (elem)
- (if (eq index (setq i (1+ i)))
- newitem
- elem
- )
- )
- lst
- )
- )
- There's a number of posts here offering solutions, but
- if you need to perform multiple replacements of elements
- in the same list, by position, then none of the solutions
- you've seen so far, including the one Reini posts a link
- to (with a password), are very effective.
- If you have to do many replacements, you should
- index your list, by cons'ing each element with a
- unique integer value. This allows you to use (SUBST)
- to quickly replace elements:
- (defun index-list (lst / i)
- (setq i -1)
- (mapcar '(lambda (elem) (cons (setq i (1+ i)) elem)) lst)
- )
- Given the list (A B C D E F), the above function
- returns the list:
- ((0 . A) (1 . B) (2 . C) (3 . D) ...)
- With this resulting list, you can now use (subst)
- to replace only one element by position. This is
- much more effecient if you have many replacements
- to perform on the same list.
- To replace an element at a given position:
- (setq indexed-list
- (subst (cons <index> <newvalue>)
- (nth <index> indexed-list)
- indexed-list
- )
- )
- You can still quickly reference elements in the list
- by position, using (cdr (nth <index> <indexed-list>))
- Or, once you're finished replacing elements, you can
- just do (mapcar 'cdr <indexed-list>) to remove the
- indexing.
- ;;; by Tony Tanzillo ===============================
- ;;; by Reini Urban
- (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)))))
- ;|
- ;;; old slower versions:
- (defun STD-RPLACE (lst i new)
- (if (< -1 i (length lst)) ; fixed v0.3003
- (append (std-firstn i lst)
- (list new)
- (std-nthcdr (1+ i) lst))
- lst))
- |;
- ;;; by Marc'Antonio Alessi
- ;;; newitem /= nil
- (defun ALE_SUBST_NTH (index newitem lst / len r_lst olditem )
- (if (and newitem (> (setq len (- (length lst) (1+ index))) -1))
- (progn
- (setq
- r_lst (reverse lst)
- olditem (nth index lst)
- )
- (while (/= index (length (setq r_lst (cdr (member olditem r_lst))))))
- (while (/= len (length (setq lst (cdr (member olditem lst))))))
- (append (reverse r_lst) (list newitem) lst)
- )
- lst
- )
- )
|