Для пустых и одноэлементных списков мы просто возвращаем список. В противном случае мы видим, совпадает ли первый элемент в списке с элементом, который мы пытаемся удалить. Если это элемент, который мы пытаемся удалить, то мы удаляем следующее вхождение этого элемента в остальной части списка, если нет, мы повторяем в остальной части списка.
(define (remove-2nd item l)
(cond
((null? l) '())
((null? (cdr l)) l)
(else (if (equal? item (car l))
(cons (car l) (remove item (cdr l)))
(cons (car l) (remove-2nd item (cdr l)))))))
Использование сопоставления с образцом в Racket:
(define (remove-2nd e l)
(match l
[(or `() `(e)) l]
[(cons f r) (cons f (if (equal? e f) (remove e r) (remove-2nd e r)))]))
Некоторые тесты:
(remove-2nd 1 '())
; => '()
(remove-2nd 1 '(1))
; => '(1)
(remove-2nd 1 '(2))
; => '(2)
(remove-2nd 1 '(2 2))
; => '(2 2)
(remove-2nd 1 '(1 1))
; => '(1)
(remove-2nd 1 '(1 2))
; => '(1 2)
(remove-2nd 'c '(a b c d c x c))
; => '(a b c d x c)