用于按不同类型的列表中的值进行搜索的功能

时间:2016-08-31 10:13:07

标签: list scheme racket

我有两种带键值对的列表:

(define pairs1 (list (list 1 2)(list 10 20)(list 100 200)))
(define pairs2 (list (cons 1 2)(cons 10 20)(cons 100 200)))

我想通过一个函数在两种列表中按值搜索。我试过跟随(其中一个'cdr'和其他fn中的'second'),但它们分别使用一个列表:

(define (assoc_val1 val spair)
  (for/list ((item spair) #:when (equal? (cdr item) val))
      item))

(define (assoc_val2 val spair)
  (for/list ((item spair) #:when (equal? (second item) val))
      item))

我可以使用适用于这两种列表的功能吗?另外,是否有一个很好的链接解释(列表1 2),(利弊1 2)和'(1 2)之间的区别?

编辑:修改@Sylwester提供的答案,以下功能可以检测并处理两个列表:

(define (assoc2* haystack needle [is-equal? equal?] )
  (if (list? (car haystack))
      (findf (λ (e) (is-equal? needle (second e))) haystack)
      (findf (λ (e) (is-equal? needle (cdr e))) haystack)
      ))

(assoc2* pairs1 20)
(assoc2* pairs2 20)

输出:

'(10 20)
'(10 . 20)

1 个答案:

答案 0 :(得分:1)

只需添加#:accessor作为关键字参数或可选参数:

;; Fully compatible with assoc but allows for searching any part 
(define (assoc* haystack needle [is-equal? equal?] #:accessor [accessor car])
  (findf (λ (e) (is-equal? needle (accessor e))) haystack))

(assoc* pairs1 20 #:accessor cadr) ; ==> (10 20)
(assoc* pairs2 20 #:accessor cdr)  ; ==> (10 . 20)