Im learning Racket and have some troubles.
I want to iterate over a list and find the index of some value. I have the following code:
(define (index list entry)
(define index 0)
(for ([i list])
#:break (equal? i entry)
(+ index 1))
index)
But the function always returns 0. Can anyone point out my mistake?
I know that there are functions for that, but I want to learn the syntax.
First of, the easiest way to get the index of an element in a list is index-of
:
> (index-of '(1 3 5 2 4) 5)
2
Another way I will sometimes do it is using the in-naturals
sequence. So taking your code:
(define (index list entry)
(for/last ([i list]
[index (in-naturals)])
#:break (equal? i entry)
index))
This works because for
loop constructs iterates as many times as the shortest sequence. in-naturals
will go on forever, so it will count only as many elements are in list
, and still break when your #:break
clause is met.
A third option is to use for/fold
, again based on your code:
(define (index list entry)
(for/fold ([acc 0])
([i list])
#:break (equal? i entry)
(add1 acc)))
This works because acc
acts as an accumulator, and gets incremented every iteration until your #:break
clause is met.
Finally, your original code has two primary problems.
First, the for
form always returns (void)
. You need to use for/last
if you want it to return the last element.
Second, the +
function only adds two numbers. It does not store the result back into the variable. So if you really want to use mutation here, you would need to do:
(define (index list entry)
(define index 0)
(for ([i list])
#:break (equal? i entry)
(set! index (+ index 1)))
index)
But again, I highly recommend just using index-of
, since its already in the standard library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With