我有两种带键值对的列表:
(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)
答案 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)