Racket:编写一个函数来访问结构的一个组件

时间:2015-12-17 09:51:08

标签: racket

我想抽象出以下函数:

(define (road_length1 n)
  (road-length (node-road1 n)))
(define (road_length2 n)
  (road-length (node-road2 n)))
(define (road_length3 n)
  (road-length (node-road3 n)))

我对节点和道路的结构是这样的:

  (define-struct node [Letter road1 road2 road3])
  (define-struct road [name length])

因此我希望能够从节点访问给定道路的长度,如下所示:

 (define (road_length n road_number)
    (road-length (node-(road_number) n)))

然而,这不起作用

2 个答案:

答案 0 :(得分:2)

最简单的方法是将节点存储在vectorlist

要做到这一点,我会将其存储在struct中,如下所示:

(struct node (letter roads))

(作为旁注,structdefine-struct更好(或至少是更新)创建结构的方式。)

一旦你这样做,你可以将你想要的道路索引作为参数传递给函数。

(define (road-length node road)
  (list-ref (node-roads node) road))

(我应该注意到'技术上'有一种方法可以用宏来完成你想要的东西,但我几乎可以肯定,在这种情况下,当函数运行正常时,它会有点过分。)

答案 1 :(得分:0)

我个人觉得道路编号已经闻起来很糟糕了。我会改变它:

(define-struct node [letter roads] #:constructor-name make-raw-node)
(define (make-node letter . roads)
  (make-raw-node letter (list->vector roads)))

(define (node-road-length node road-index)
  (road-length (vector-ref (node-roads node) road-index)))

请注意,在理智的编程语言中,我们开始从0开始索引元素,因此道路编号在[0,2]范围内。

如果您真的想在名称中包含索引,那么您可以在索引及其访问者之间建立映射:

(define node-road-length
  (let ((lookup (vector node-road1 
                        node-road2 
                        node-road3)))
    (lambda (node road-index)
      (road-length ((lookup road-index) node)))))