Подтвердить что ты не робот

Заменить элемент в списке объединений в elisp

У меня есть alist в emacs lisp как:

(setq a1
 '((:k1 . 1)
   (:k2 . 2)
   (:k3 . 3)))

и я хочу изменить значение: от k1 до 10, например (:k1 . 10). Как это сделать?

Я пробовал (setf (assoc :k1 a1) '(:k1 . 10)) - он не работал.

4b9b3361

Ответ 1

С помощью alists вы обычно добавляете новые минусы перед старым, чтобы "затенять" старое значение, например:

(add-to-list 'a1 '(:k1 10))

После этого (assoc :k1 a1) вернет 10.

Если вы хотите "отменить" свое изменение, поэтому assoc снова возвращает ваше старое значение, используйте этот код:

(setq a1 (delq (assoc :k1 a1) a1))

Это приведет к удалению соответствия FIRST для :k1 из a1.

Ответ 2

Макрос setf не знает о assoc, но вы можете использовать этот подход несколько более вручную:

(let ((item (assoc :k1 a1)))
  (setf (car item) :k1)
  (setf (cdr item) 10))

и если все, что требуется, - установить cdr для данного автомобиля (вместо замены обоих), тогда мы можем упростить это:

(setf (cdr (assoc :k1 a1)) 10)

Ответ 3

Начиная с Emacs 25.1, alist-get - это форма места, которую вы можете сделать:

(setf (alist-get :k1 a1) 10)

Ответ 4

Как насчет assq-delete-all:

(setq sql-product-alist
      (cons '(ms-tsql :server ....)
            (assq-delete-all 'ms-tsql sql-product-alist)))

Ответ 5

Здесь функция, основанная на предположении гавенько -

(defun alist-set (alist-symbol key value)
  "Set KEY to VALUE in alist ALIST-SYMBOL."
  (set alist-symbol
        (cons (list key value) 
              (assq-delete-all key (eval alist-symbol)))))

использование -

(let ((foo '((a 1) (b 2))))
  (alist-set 'foo 'a 3)
  foo) ; => ((a 3) (b 2))