Racket - 以数字形式输出字符串在列表中的位置(从左到右)

Racket - outputting in numerical form the placement of a string within a list (from left to right)

我的任务是创建一个函数,以数字形式告诉列表中字符串的位置(从左到右),以便:

(position "a" '("a" "b" "c" "d" "e"))

returns 1

(position "b" '("a" "b" "c" "d" "e"))

returns 2 和

(position "z" '("a" "b" "c" "d" "e"))

returns#f

我是这样写的:

(define (position x L)
  (if (pair? L)
      (if (equal? x (car L))
          1
          (+ 1 (position x (cdr L)))
          )
      #f)
  )

不幸的是,

(position "z" '("a" "b" "c" "d" "e"))

根本不起作用,因为它正在尝试将 #f 添加到数字中。有什么办法摆脱这种泡菜吗?

我通过以下方式修复了它:

(define (position x L)
  (if (pair? L)
      (if (equal? x (car L))
          1
          (let ((p-cdr-L (position x (cdr L))))
            (if p-cdr-L
                (+ 1 p-cdr-L)
                #f)))
      #f))

你的回答是正确的,但我会建议一个不同的方法:通过使用 named let for implementing tail recursion we'll obtain a more efficient solution. Also notice how using cond(而不是嵌套 ifs)简化事情:

(define (position x L)
  (let loop ((L L) (acc 1))
    (cond ((null? L) #f)
          ((equal? x (car L)) acc)
          (else (loop (cdr L) (add1 acc))))))

此外,在 SRFI-1 库中我们可以找到 list-index 函数 almost returns 你想要什么,我们只需要添加一个结果将其转换为基于 1 的索引:

(require srfi/1)

(define (position x L)
  (cond ((list-index (curry equal? x) L) => add1)
        (else #f)))