球拍遍历列表并获得索引

时间:2020-02-05 16:47:44

标签: functional-programming racket

我正在学习球拍,遇到了一些麻烦。

我想遍历一个列表并找到某个值的索引。我有以下代码:

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

但是该函数总是返回0。有人可以指出我的错误吗?

我知道有一些功能,但是我想学习语法。

1 个答案:

答案 0 :(得分:6)

首先,获取列表中元素索引的最简单方法是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循环构造的迭代次数是最短序列的次数。 in-naturals将永远存在,因此它将仅计算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,因为它已经在标准库中了。