定义结构和抽象列表函数



我正在尝试创建一个函数games-won,该函数使用游戏列表,结果和字符串,名称,并生成name赢得的结果中的games数。

例如:

(define-struct game (winner loser high low))
(check-expect (games-won (list (make-game "Lori" "Troy" 52 34)
                         (make-game "Mary" "Lori" 30 20)) "Lori") 1)

以下是我到目前为止所拥有的:

(define (won? game name)
  (equal? (game-winner game) name))
(define (wonlst results)
  (filter won? results))
(define (lst-length lst)
  (cond
    [(empty? lst)  0]
    [(cons? lst)   (+ 1 (length (rest lst)))]))
(define (games-won results)
 (cond
   [(cons? (wonlst results)) (lst-length (wonlst results))]
   [else 0]))

任何人都可以帮助纠正我的代码中的错误,并告诉我如何使用local并将函数放在一起?

以下是修复:

  • 正如测试所建议的那样,games-won应该接受两个参数:结果列表和名称。所以我们添加一个参数 - name - 到 games-won .
  • 您不需要自定义lst-length功能,只需使用length即可。此外,games-won无需担心在else情况下返回0。基本情况由列表抽象处理。
  • 请注意,won?接受两个输入,但filter中的谓词函数只接受一个输入。所以我们从won?中删除name.一旦我们将won?放入本地,它就可以使用周围函数上下文中的name
  • 我们把一个当地人放在games-won,把两个帮手——won?won-lst——放在本地。
  • 您应该使用 string=? 而不是 equal?,因为我们知道namewinner game字段始终是字符串。
(define-struct game (winner loser high low))
; games-won : [List-of Game] String -> Number
(define (games-won results name)
  (local (; won? : Game -> Boolean
          (define (won? game)
            (string=? (game-winner game) name))
          ; wonlst : [List-of Game] -> [List-of Game]
          (define (wonlst results)
            (filter won? results)))
    (length (wonlst results))))

(define my-games1 (list (make-game "Lori" "Troy" 52 34)
                        (make-game "Mary" "Lori" 30 20)))
(check-expect (games-won my-games1 "Lori") 1)

我们可以将所有内容与lambda一起放在一个函数中,如下所示:

(define (games-won results name)
  (length (filter (λ (game) (string=? (game-winner game) name)) results)))

如何使用local

局部表达式具有以下形状:

(local [definition ...] body-expression)

在方括号内,您可以放置任意数量的定义(即 根据需要define s、define-struct s(,并在局部(body-expression(的正文中,您可以将任何可能使用或不使用定义的表达式放在方括号内。这些定义仅在正文中可用。

从 HtDP,以下是我们使用局部变量进行计算的方式:

  • 我们重命名本地定义的常量和函数,以使用程序中其他地方未使用的名称。

  • 我们将局部表达式
  • 中的定义提升到顶层,接下来评估局部表达式的主体。