2013-11-11 3 views
1

Я пытаюсь написать функцию в Common Lisp, которая удаляет элемент из списка. Вот что я написал до сих пор:Удаление элемента из списка в Common Lisp

(defun aux-remove-fio (lst toremove) 
    (if (equal (first lst) toremove) 
     (pop lst) 
     (aux-remove-fio (rest lst) toremove)))) 

Когда я проверить функцию, вот результат:

CG-USER(49): a3 
((1 (1 . 1) (1 . 2)) (2 (2 . 1) (1 . 2))) 
CG-USER(50): (pop a3) 
(1 (1 . 1) (1 . 2)) 
CG-USER(51): a3 
((2 (2 . 1) (1 . 2))) 
CG-USER(52): (setf a3 '((1 (1 . 1) (1 . 2)) (2 (2 . 1) (1 . 2)))) 
((1 (1 . 1) (1 . 2)) (2 (2 . 1) (1 . 2))) 
CG-USER(53): (aux-remove-fio a3 '(1 (1 . 1) (1 . 2))) 
(1 (1 . 1) (1 . 2)) 
CG-USER(54): a3 
((1 (1 . 1) (1 . 2)) (2 (2 . 1) (1 . 2))) 

Может кто-нибудь объяснить, почему моя функция не работает?

ответ

2

Да. Ваша функция изменяет значение своей локальной переменной, lst --- ничего более.

Вот простой пример, показывающий то же самое:

(setq a3 '(1 2 3)) ; (1 2 3) 
(defun foo (xs) (setq xs (cdr xs))) ; Change value of xs. 

;; Change value of xs to (2 3). Its initial value is the value of a3, i.e., (1 2 3) 
(foo a3) 
a3 ; => (1 2 3) 

После foo называется, a3 все еще указывает на оригинальный минусы ячейки, автомобиль 1 и чьи корд является сотой же недостатки, как и раньше, с автомобилем 2 и т. д. Все, что вы сделали, я нанесли локальную переменную xs, указывающую на cdr из ячейки cons, на которую он указывал первоначально, которая была той же самой ячейкой, что и a3.

Если вы хотите, чтобы ваша функция, чтобы изменить значение глобальной переменной a3, то сделать это прямо:

(defun foo() (pop a3)) 

Или если вы просто хотите функцию, которая появляется первый элемент от значения списка из специального переменная, то у вас есть такая функция: pop --- просто используйте (pop a3).

Если вы хотите функцию, которая изменяет значение глобальной переменной, которую вы передаете его, а затем передать переменную (т.е. символ), а не его значение:

(defun foo (var) 
    (let* ((val (symbol-value var)) 
     (head (car val))) 
    (set var (cdr val)) 
    head)) 

(foo 'a3) ; Pop off a3's head and return it. 
a3 ; Now a3 has lost its head. 

Это определение foo походит на простая форма pop, за исключением того, что она является функцией, поэтому оценивает ее аргумент.

+0

Спасибо, очень много! Я знаю, это прекрасно! :) Еще раз спасибо! – ssimoes04

0

Это мое простое решение. Я определяю функцию в REPL

CL-USER> (defun remove-element (mylist n) 
      (append 
      (subseq mylist 0 n) 
      (subseq mylist (1+ n)))) 

затем запустить его (ошибки на вашем Лисп реализации может отличаться)

CL-USER> (remove-element '(1 2 3 4 5) 0) 
(2 3 4 5) 
CL-USER> (remove-element '(1 2 3 4 5) 1) 
(1 3 4 5) 
CL-USER> (remove-element '(1 2 3 4 5) 5) 
; Evaluation aborted on #<SB-KERNEL:BOUNDING-INDICES-BAD-ERROR ... 
CL-USER> (remove-element '(1 2 3 4 5) -1) 
; Evaluation aborted on #<TYPE-ERROR ... 
Смежные вопросы