lisp中的replace函数

lisp中的replace函数,lisp,common-lisp,Lisp,Common Lisp,我想在给定的列表中替换单词,但当列表中给出替换单词时,这太难了 例如(myreplace’((狗猫)(可爱可爱))(我的狗很可爱))->(我的猫很可爱) 救救我 这是一个递归版本: (defun myreplace (subst-alist replace-in) (when replace-in (let ((found (assoc (car replace-in) subst-alist :test #'eq))) (cons (if found

我想在给定的列表中替换单词,但当列表中给出替换单词时,这太难了

例如(myreplace’((狗猫)(可爱可爱))(我的狗很可爱))->(我的猫很可爱)


救救我

这是一个递归版本:

(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))))))
如果您喜欢这种方法,这里有一个迭代版本:

(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)))))

这里有一个解决方案,它使用
reduce
调用
substitute
,以增量方式转换原始序列:

(defun myreplace (substitutions sequence)
  (reduce (lambda (seq substitution)
            (destructuring-bind (old new) substitution
              (substitute new old seq)))
          substitutions
          :initial-value sequence))
编辑:Trey使用
assoc
(而不是
assq
,这是Emacs Lisp)查找替换的想法非常好。通过使用内置支持构建新列表的操作符,即
mapcar
或带有
collect
子句的
loop
,可以简化该操作:

(defun myreplace (substitutions list)
  (mapcar (lambda (elt)
            (let ((substitution (assoc elt substitutions)))
              (if substitution
                  (second substitution)
                  elt)))
          list))


谢谢,我进入了Emacs lisp,而不是普通lisp。
(defun myreplace (substitutions list)
  (loop for elt in list
     for substitution = (assoc elt substitutions)
     when substitution collect (second substitution)
     else collect elt))