replace function in lisp
i want to substitute words in a given list but its so ha开发者_如何学Pythonrd when the replacing word is given by list
for example (myreplace '((dog cat)(cute lovely)) '(my dog is cute)) -> (my cat is lovely)
help me!
Here's a recursive version for you:
(defun myreplace (subst-alist replace-in)
(when replace-in
(let ((found (assoc (car replace-in) subst-alist :test #'eq)))
(cons
(if found
(cadr found)
(car replace-in))
(myreplace subst-alist (cdr replace-in))))))
And here's an iterative version, if you prefer that approach:
(defun myreplace (subst-alist replace-in)
(let (result)
(dolist (word replace-in (reverse result))
(let ((found (assoc word subst-alist :test #'eq)))
(push (if found (cadr found) word)
result)))))
Here's a solution that uses reduce
to call substitute
for each of the old-new pairs, incrementally transforming the original sequence:
(defun myreplace (substitutions sequence)
(reduce (lambda (seq substitution)
(destructuring-bind (old new) substitution
(substitute new old seq)))
substitutions
:initial-value sequence))
EDIT: Trey's idea to use assoc
(not assq
, that's Emacs Lisp) for finding a substitution is very nice. Using that can be simplified by using an operator that has built-in support for building a new list, i.e. mapcar
or loop
with the collect
clause:
(defun myreplace (substitutions list)
(mapcar (lambda (elt)
(let ((substitution (assoc elt substitutions)))
(if substitution
(second substitution)
elt)))
list))
or
(defun myreplace (substitutions list)
(loop for elt in list
for substitution = (assoc elt substitutions)
when substitution collect (second substitution)
else collect elt))
精彩评论