2016-12-02 2 views
0

Привет, я новичок в AutoCad lisp и стараюсь немного ускорить работу с помощью простой процедуры, но я ударил стену и не могу понять это, и у меня есть сильное наполнение, является простым решением. Так что ...Список обновлений Lisp

Я сделал список с именем "koord":

(setq koord (list (cons "1" "10,10,10"))) 

результат является точечная пара: ("1" . "10,10,10")

после этого я добавить к этому списку, например:

(setq koord (append koord (list (cons "2" "20,20,20")))) 
(setq koord (append koord (list (cons "3" "30,30,30")))) 

теперь результат: ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30")

в данный момент Мне бы хотелось, чтобы t о обновит второй пунктирную пару и сделать мой список выглядит следующим образом:

("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30")

, но я не знаю, как ... Если я добавляю как этот

(setq koord (append koord (list (cons "2" "60,60,60")))) 

, чем я получаю этот результат :

("1" . "10,10,10") ("2" . "20,20,20") ("2" . "60,60,60") ("3" . "30,30,30") 

, который не был бы слишком плохо, если я знаю, как получить этот один ("2" . "60,60,60")

Если я пытаюсь

(assoc "2" koord) 

он возвращает первое вхождение т.е. ("2" . "20,20,20")

Итак, есть ли способ, чтобы не добавить, но обновить значение в пунктирной паре или получить последний прилагаемую - не первый?

+0

результат '(список (против "1" "10,10,10"))' не '("". "1 10,10,10")' 'а ((«1». «10,10,10")) ' – Sylwester

+1

вместо добавления, просто добавьте его так:' (setq koord (cons (cons "2" "60,60,60") koord)) '. В следующий раз, когда вы вызываете '(assoc" 2 "koord)', вы получите новую пару ''(« 2 ».« 60,60,60 »)'. Предыдущая пара будет по-прежнему находиться в списке 'koord', но не будет видна' assoc', которая всегда выбирает первое совпадение. –

+0

Привет. Благодаря! Я попробовал ваше решение, и он работает – Mario

ответ

1

Если вы хотите обновить запись, вы можете сделать это:

(def alist-update (alist key value) 
    "Update the value of a key or add a cell." 
    (let ((cell (assoc key alist))) 
    (if cell 
     (setf (cdr cell) value) 
     (acons key value alist)))) 
(setq alist (alist-update() 1 "a")) 
(assoc 1 alist) 
==> (1 . "a") 
(setq alist (alist-update alist 1 "b")) 
(assoc 1 alist) 
==> (1 . "b") 

В то время как вы используете AutoLisp и не Common Lisp (обратите внимание, что CL assoc использует eql для сравнения по умолчанию, и, таким образом, вернуть nil для (assoc "1" ...)) или Emacs Lisp, я по-прежнему предлагаю вам ознакомиться с руководством по использованию Association Lists.

+0

Спасибо! Я также читал в то же время на каком-то форуме, который я могу использовать: (ассоциировать «2» (обратный коорд)) - в моем примере. Это «обратное» даст мне последнюю введенную пару – Mario

0

Учитывая ваш список точечных пар:

_$ (setq koord '(("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30"))) 
(("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30")) 

Ниже будет заменить второй пункт для нового пункта:

_$ (subst '("2" . "60,60,60") (assoc "2" koord) koord) 
(("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30")) 

Однако, обратите внимание, что это будет заменить все вхождения исходного элемента , например:

_$ (setq koord '(("2" . "20,20,20") ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30") ("2" . "20,20,20"))) 
(("2" . "20,20,20") ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30") ("2" . "20,20,20")) 

_$ (subst '("2" . "60,60,60") (assoc "2" koord) koord) 
(("2" . "60,60,60") ("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30") ("2" . "60,60,60")) 
Смежные вопросы