Наиболее эффективный (обход списка один раз) способ сделать это состоит в том, чтобы определить функцию, которая проходит по списку элемент за элементом. Функция хранит список элементов, которые уже находятся в дублированном списке.
Преимущество этого решения перед @Tikhon Jelvis в том, что элементы списка не должны быть в порядке, чтобы быть дедуплицированными.
Дана функция elem
, которая сообщает, является ли a
элементом l
:
(define (elem? a l)
(cond ((null? l) #f)
((equal? a (car l)) #t)
(else (elem? a (cdr l)))))
Мы можем просмотреть список, сохранив каждый элемент, который мы не видели раньше:
(define (de_dupe l_remaining already_contains)
(cond ((null? l_remaining) already_contains)
((elem? (car l_remaining) already_contains) (de_dupe (cdr l_remaining) already_contains))
(else (de_dupe (cdr l_remaining) (cons (car l_remaining) already_contains)))))
Примечание: для эффективности это возвращает элементы в обратном порядке