Racket Iterate over list and get Index

Gam*_*r41 5 functional-programming racket

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)
Run Code Online (Sandbox Code Playgroud)

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.

Lei*_*sen 6

首先,获取列表中元素索引的最简单方法是index-of

> (index-of '(1 3 5 2 4) 5)
2
Run Code Online (Sandbox Code Playgroud)

我有时会使用的另一种方法是使用in-naturals序列。所以拿你的代码:

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

这是有效的,因为for循环构造迭代次数与最短序列一样多。in-naturals将永远持续下去,因此它只会计算 中的元素数量list,并且在#:break满足您的子句时仍然会中断。

第三个选项是使用for/fold, 再次基于您的代码:

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

这是有效的,因为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)
Run Code Online (Sandbox Code Playgroud)

但同样,我强烈建议只使用index-of,因为它已经在标准库中。