Не уверен, что вы хотите, но сначала запустите его просто с индексом, это примерно то, как вы должны «думать» со Схемой, сначала начните с «Что, если это был первый элемент?», Тогда ответ таков: конечно, это должно быть остальной частью списка. А затем «Ну, что, если это не первый», тогда ответ «Это должно состоять из первого до результата той же самой процедуры, примененной ко всем остальным.», Это все, что нужно Схеме информации в этом, и во многих случаях на самом деле.
(define (slice-out lst k)
(if (<= k 0) (cdr lst) ; if we want to remove the first (0) element, surely the result is simply the tail of the list?
(cons (car lst) ; if it's higher than 0, we just cons the first element...
(slice-out (cdr lst) (- k 1))))) ; to the result of the same method applied to the tail but with one lower k.
> (slice-out '(a b c d e) 2)
===>(a b d e)
Эта функция возвращает ошибку, если список слишком короткий для индекса.
Однако, если вы хотите вырезать по некоторому равенству с другим объектом, этого примера достаточно, теперь мы больше не вырезаем его из того, что достигли 0, но если он идентичен примеру поиска:
(define (slice-out-by-equality lst search)
(if (equal? (car lst) search) (cdr lst)
(cons (car lst)
(slice-out-by-equality (cdr lst) search))))
> (slice-out-by-equality '(a b c d e) 'c)
===> (a b d e)
Используя те же принципы, этот возвращает ошибку, если элемент не найден .
Дело в том, что схема имеет много разновидностей сравнений на равенство, поэтому нам действительно нужно:
(define (make-slice-out comparison)
(lambda (lst search)
(let loop ((lst lst))
(cond
((null? lst) '())
((comparison (car lst) search) (cdr lst))
(else (cons (car lst) (loop (cdr lst))))))))
Этот пример показывает, что такое Scheme, не уверен, что вы знакомы с ним, но мы использовали здесь замыкание, эта функция на самом деле принимает в качестве аргумента любую двоичную функцию сравнения, а затем вычисляет требуемую функцию, он также очищен, он больше не делает ошибку, если не найден, он возвращает, он просто возвращает старый список, потому что, если он достигает конца списка, но ничего еще не удалено, он просто возвращает его в () .
> ((make-slice-out =) '(1 2 3 6 3) 6)
===> (1 2 3 3); we just made an anonymous function here.
Но, вспомнив нашу первоначальную функцию, теперь мы можем определить ее просто так, предоставляя предикат «равно?» наша новая функция фактически оценивает нашу старую функцию (с важным активом, который теперь очищается):
(define slice-out-by-equality (make-slice-out equal?))
И, есть еще двоичное сравнение, как насчет этого более экзотического примера:
(define slice-out-less-than (make-slice-out <))
Мы создали функцию, которая вырезает первый элемент, который строго меньше, чем наш поисковый запрос, таким образом, это работает:
> (slice-out-less-than '(573 284 238 174 92 47) 100)
====> (573 284 238 174 47)
Хотя 47 также меньше 100, 92 является первым из тех, кто есть.