当然,这是一个微不足道的工具,但我觉得Racket内置了一些内容。我是否正确直觉,如果是,那么功能是什么?
答案 0 :(得分:12)
奇怪的是,在Racket中没有内置的过程来查找列表中元素的基于0的索引(相反的过程确实存在,它被称为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))))))
但 是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
<强>更新强>
从Racket 6.7开始,index-of
现在是标准库的一部分。享受!
答案 1 :(得分:6)
这是一个非常简单的实现:
(define (index-of l x)
(for/or ([y l] [i (in-naturals)] #:when (equal? x y)) i))
是的,这样的东西应该添加到标准库中,但这样做有点棘手,所以没有人到达那里。
但是,请注意,这是一个很少有用的功能 - 因为列表通常被视为仅使用第一个/其他习惯用法解构而不是直接访问元素的序列。更重要的是,如果你有一个使用它,你是一个新手,那么我的第一个猜测将是你滥用列表。鉴于此,增加这样的功能可能会使这些新手更易获取。 (但最终仍会加入。)
答案 2 :(得分:0)
还可以使用内置功能&#39; member
&#39;如果项目在列表中不存在,则提供以所需项目开头的子列表或#f
。下面比较原始列表的长度和成员返回的子列表:
(define (indexof n l)
(define sl (member n l))
(if sl
(- (length l)
(length sl))
#f))
对于许多情况,可能需要列表中所有项目出现的索引。可以按如下方式获取所有索引的列表:
(define (indexes_of1 x l)
(let loop ((l l)
(ol '())
(idx 0))
(cond
[(empty? l) (reverse ol)]
[(equal? (first l) x)
(loop (rest l)
(cons idx ol)
(add1 idx))]
[else
(loop (rest l)
ol
(add1 idx))])))
For/list
也可用于此:
(define (indexes_of2 x l)
(for/list ((i l)
(n (in-naturals))
#:when (equal? i x))
n))
测试:
(indexes_of1 'a '(a b c a d e a f g))
(indexes_of2 'a '(a b c a d e a f g))
输出:
'(0 3 6)
'(0 3 6)