farquhar@cs.utexas.edu (Adam Farquhar) (08/31/89)
Is there an elegant way to perform substitutions in a sequence where the new item may be of a different length than the old item? E.g. (substitute-it "Common lisp, the Language" "CLtL" "The right function does not seem to be in CLtL.") => "The right function does not seem to be in Common Lisp, the Language." or (substitute-it "abc" "1" "10101") => "abc0abc0abc" Even better would be a function which took a list of (new . old) pairs and substituted the corresponding NEW for each OLD occuring in the sequence. Thanks, Adam Farquhar.
Duchier-Denys@cs.yale.edu (Denys Duchier) (08/31/89)
In article <425@ai.cs.utexas.edu>, farquhar@cs (Adam Farquhar) writes: > Is there an elegant way to perform substitutions in a sequence where > the new item may be of a different length than the old item? E.g. > > (substitute-it "Common lisp, the Language" "CLtL" > "The right function does not seem to be in CLtL.") > => > "The right function does not seem to be in Common Lisp, the Language." > > or (substitute-it "abc" "1" "10101") > => > "abc0abc0abc" How about: (defun substitute-it (new old seq) (let ((i (search old seq))) (if (null i) seq (concatenate (type-of seq) (subseq seq 0 i) new (substitute-it new old (subseq seq (+ i (length old)))))))) --Denys
chewy@apple.com (Paul Snively) (09/05/89)
In article <425@ai.cs.utexas.edu> farquhar@cs.utexas.edu (Adam Farquhar) writes: > Even better would be a function which took a list of (new . old) pairs > and substituted the corresponding NEW for each OLD occuring in the > sequence. > > Thanks, > Adam Farquhar. Sounds suspiciously like the SUBLIS function to me! ___________________________________________________________________________ chewy@apple.com Just because I work for Apple Computer, Inc. doesn't mean that they believe what I believe or vice-versa. ___________________________________________________________________________
gupta@prlhp1.prl.philips.co.uk (gupta) (09/12/89)
In article <4022@internal.Apple.COM> chewy@apple.com (Paul Snively) writes: >In article <425@ai.cs.utexas.edu> farquhar@cs.utexas.edu (Adam Farquhar) >writes: >> Even better would be a function which took a list of (new . old) pairs >> and substituted the corresponding NEW for each OLD occuring in the >> sequence. >> >> Thanks, >> Adam Farquhar. > >Sounds suspiciously like the SUBLIS function to me! > Ah well, SUBLIS is not flexible enough for Adam's purposes as it requires its second arg. to be a tree. Adam wanted to operate on a sequence, which could be a list but could also be a string or a simple or bit vector. (O.K. - so I'm being pedantic, but a tree is only a sub-type of a sequence. Also, Adam wanted the args in new.old form wheras SUBLIS requires them in old.new form.) The following does not do any error-handling and does not accept the first argument in assoc-list form as required, but that's easy to change. BTW, I extended the contribution made by Denys Duchier in an earlier posting. Try this : (defun subs (new old seq) (etypecase seq (simple-string (let ((i (search old seq))) (if (null i) seq (concatenate (type-of seq) (subseq seq 0 i) new (subs new old (subseq seq (+ i (length old)))))))) (cons (subst new old seq :test #'equal)) ((or (simple-bit-vector) (vector)) (let ((new-seq (copy-seq seq))) (dotimes (n (length seq) new-seq) (if (eq old (elt new-seq n)) (setf (elt new-seq n) new))))))) (defun substitute-it (&rest args) (if (oddp (length args)) (let ((new-old-pairs (butlast args)) (answer (first (last args))) new-item) (declare (special answer)) (loop (if (setq new-item (pop new-old-pairs)) (setq answer (subs new-item (pop new-old-pairs) answer)) (return answer)))))) (defun er (seq) (terpri) (dotimes (n (length seq)) (format t "~a " (elt seq n))) (values)) ------------------------------------ > (substitute-it "Common lisp, the Language" "CLtL" "functions" "function" "do" "does" "appear" "seem" "The right function does not seem to be in CLtL.") "The right functions do not appear to be in Common lisp, the Language." ------------------------------------ > (substitute-it 'gobble 'a '(a b c d (a b c (a b (a))))) (GOBBLE B C D (GOBBLE B C (GOBBLE B (GOBBLE)))) ------------------------------------ > (setq sv (make-sequence 'simple-vector 6 :initial-element 'a)) #<Simple-Vector T 6 11AB3AB> > (setf (elt sv 2) 'b (elt sv 2) 'b) B > (er sv) A A B A B A >(substitute-it 'as-a-cloud 'a 'i-sailed 'b sv) #<Simple-Vector T 6 11683AB> > (er *) AS-A-CLOUD AS-A-CLOUD I-SAILED AS-A-CLOUD I-SAILED AS-A-CLOUD ------------------------------------ > (setq sb (make-sequence 'bit-vector 6 :initial-element 0 )) #<Simple-Bit-Vector 6 1183E93>> > (setf (elt sb 2) '1 (elt sb 4) '1) 1 >(er sb) 0 0 1 0 1 0 > (substitute-it 1 0 0 1 sb) #<Simple-Bit-Vector 6 1164963> > (er *) 0 0 0 0 0 0 ------------------------------------