如何在Racket中找到列表中元素的索引?

Ale*_*lex 8 lisp scheme racket

当然,这是一个微不足道的工具,但我觉得Racket内置了一些内容.我是否正确直觉,如果是,那么功能是什么?

Ósc*_*pez 12

奇怪的是,在Racket中没有内置的过程来查找列表中元素的从零开始的索引(相反的过程确实存在,它被调用list-ref).但是,有效实施起来并不困难:

(define (index-of lst ele)
  (let loop ((lst lst)
             (idx 0))
    (cond ((empty? lst) #f)
          ((equal? (first lst) ele) idx)
          (else (loop (rest lst) (add1 idx))))))
Run Code Online (Sandbox Code Playgroud)

但是,一个类似的过程中srfi/1,这就是所谓的list-index,你可以通过传递正确的参数获得预期的效果:

(require srfi/1)

(list-index (curry equal? 3) '(1 2 3 4 5))
=> 2

(list-index (curry equal? 6) '(1 2 3 4 5))
=> #f
Run Code Online (Sandbox Code Playgroud)

UPDATE

从Racket 6.7开始,index-of现在是标准库的一部分.请享用!

  • 多奇怪.racket-dev邮件列表是否适合推荐将此功能添加到语言中? (2认同)
  • @Maxwell 我忘记了`list-index`。请参阅我更新的答案。 (2认同)
  • 截至Racket 6.7`index-of`现在是标准库的一部分!这可能值得编辑(尽管这个答案非常合适). (2认同)

Eli*_*lay 6

这是一个非常简单的实现:

(define (index-of l x)
  (for/or ([y l] [i (in-naturals)] #:when (equal? x y)) i))
Run Code Online (Sandbox Code Playgroud)

是的,这样的东西应该被添加到标准库中,但这样做有点棘手,所以没有人到过那里.

但是请注意,这是一个很少有用的功能 - 因为列表通常被视为仅使用第一个/其余成语解构而不是直接访问元素的序列.更重要的是,如果你有一个使用它,你是一个新手,那么我的第一个猜测将是你滥用列表.鉴于此,增加这样的功能可能会使这些新手更易获取.(但最终仍会加入.)