Ракетка Перебери список и получи Индекс - PullRequest
2 голосов
/ 05 февраля 2020

Я изучаю ракетку и у меня возникли проблемы.

Я хочу перебрать список и найти индекс некоторого значения. У меня есть следующий код:

(define (index list entry)
  (define index 0)
  (for ([i list])
    #:break (equal? i entry)
    (+ index 1))
    index)

Но функция всегда возвращает 0. Может ли кто-нибудь указать на мою ошибку?

Я знаю, что для этого есть функции, но я хочу изучить синтаксис.

1 Ответ

3 голосов
/ 05 февраля 2020

Прежде всего, самый простой способ получить индекс элемента в списке - это index-of:

> (index-of '(1 3 5 2 4) 5)
2

Другой способ, которым я иногда буду это делать, - использовать последовательность in-naturals. Итак, взяв ваш код:

(define (index list entry)
  (for/last ([i list]
             [index (in-naturals)])
    #:break (equal? i entry)
    index))

Это работает, потому что for l oop конструкций повторяется столько раз, сколько кратчайшей последовательности. in-naturals будет go вечным, поэтому будет учитываться только то количество элементов, которое содержится в list, и все равно будет прерываться при выполнении вашего предложения #:break.

Третий вариант - использовать for/fold, опять же на основе вашего кода:

(define (index list entry)
  (for/fold ([acc 0])
            ([i list])
    #:break (equal? i entry)
    (add1 acc)))

Это работает, потому что acc действует как накопитель и увеличивается на каждую итерацию до тех пор, пока не будет выполнено ваше предложение #:break.

Наконец, Ваш исходный код имеет две основные проблемы.

Во-первых, форма for всегда возвращает (void). Вам нужно использовать for/last, если вы хотите, чтобы он возвращал последний элемент.

Во-вторых, функция + добавляет только два числа. Он не сохраняет результат обратно в переменную. Поэтому, если вы действительно хотите использовать здесь мутацию, вам нужно сделать:

(define (index list entry)
  (define index 0)
  (for ([i list])
    #:break (equal? i entry)
    (set! index (+ index 1)))
  index)

Но опять же, я настоятельно рекомендую просто использовать index-of, поскольку он уже есть в стандартной библиотеке.

...