заменить функцию в LISP - PullRequest
       339

заменить функцию в LISP

0 голосов
/ 30 марта 2011

Я хочу заменить слова в данном списке, но это так сложно, когда заменяющее слово задано списком

например (myreplace '((собачья кошка) (милый, милый))' (моя собачка милая)) -> (мой милый кот)

помоги мне!

Ответы [ 2 ]

1 голос
/ 30 марта 2011

Вот рекурсивная версия для вас:

(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)))))
0 голосов
/ 30 марта 2011

Вот решение, которое использует reduce для вызова substitute для каждой из старых-новых пар, постепенно преобразовывая исходную последовательность:

(defun myreplace (substitutions sequence)
  (reduce (lambda (seq substitution)
            (destructuring-bind (old new) substitution
              (substitute new old seq)))
          substitutions
          :initial-value sequence))

РЕДАКТИРОВАТЬ: Идея Трея использовать assoc (не assq, это Emacs Lisp) для нахождения замены очень хороша. Это можно упростить с помощью оператора, который имеет встроенную поддержку для создания нового списка, то есть mapcar или loop с предложением collect:

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

или

(defun myreplace (substitutions list)
  (loop for elt in list
     for substitution = (assoc elt substitutions)
     when substitution collect (second substitution)
     else collect elt))
...