Как удалить подсписок из списка? - PullRequest
1 голос
/ 23 сентября 2019

Я хочу удалить специальный список из моего списка.Но функция удаления не помогает мне с этой проблемой.

Это для глубокого поиска в списке, и я хочу выбросить его.Я пробовал это с функцией удаления, но это не работает.

(DEFPARAMETER WB '((HALLWAY EAST OFFICE) (OFFICE WEST HALLWAY) (OFFICE NORTH KITCHEN) (KITCHEN SOUTH OFFICE) (BEDROOM WEST GARDEN) (GARDEN EAST BEDROOM) (GARDEN WEST OFFICE) (OFFICE EAST GARDEN) (GARDEN NORTH BATHROOM) (BATHROOM SOUTH GARDEN) (LAVATORY SOUTH BEDROOM) (BEDROOM NORTH LAVATORY) (LAVATORY WEST BATHROOM) (BATHROOM EAST LAVATORY) (BATHROOM WEST KITCHEN) (KITCHEN EAST BATHROOM) (STUDIO EAST KITCHEN) (KITCHEN WEST STUDIO) (STUDIO SOUTH HALLWAY) (HALLWAY NORTH STUDIO)))

(REMOVE '(BATHROOM EAST KITCHEN) WB) ;should throw (BATHROOM EAST KITCHEN) out of WB but does not work 
(REMOVE '(1 2 3) '((4 5 6) (1 2 3)))
My expected result is ((4 5 6))
But the output is ((4 5 6) (1 2 3))

1 Ответ

3 голосов
/ 23 сентября 2019

Значение по умолчанию для ключевого аргумента :test в REMOVE (и, в более общем случае, функции, принимающие параметр тестовой функции): EQL.

Когда вы пишете (remove '(1 2 3) '((1 2 3) (4 5 6))), вы не гарантируете, что оба списка, которые печатаются как (1 2 3), идентичны .Скорее всего, они представлены разными cons-ячейками:

(eql '(1 2 3) '(1 2 3))
=> NIL

Компилятор может обнаружить, что оба списка равны во время компиляции и использовать одну и ту же базовую память, что делает их EQ, но вы, как правило, не можете предположить, что этослучай.

Если, однако, вы дважды использовали один и тот же список, REMOVE будет работать так, как вы ожидаете:

(let ((a '(1 2 3))) (remove a (list a '(4 5 6))))
=> ((4 5 6))

Вышеприведенный пример также может быть записан следующим образом с переменными чтения (результат аналогичен, но весь список заключен в кавычки, вместо этого он создается во время выполнения с list):

(remove '#1=(1 2 3) '(#1# (4 5 6)))
=> ((4 5 6))

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

(remove '(1 2 3) '((1 2 3) (4 5 6)) :test #'equal)
=> ((4 5 6))

При использовании приведенного выше кода элементы сравниваются с EQUAL.

...