我有一个列表(列表(列表键值)...),我试图建立一个函数,返回与键相关的所有值。
我认为我可以使用匹配构造但是没有任何成功。
#lang racket
; should return a list starting with key, otherwise #f
(define (match-key lst key)
(match lst
[(list key val) value]
[_ #f]))
; testing data
(define test-lst
(list
(list 'title "Lorem title")
(list 'price 999.99)
(list 'colour "red")
))
(eq? "Lorem title" (match-key test-lst 'title)) ; should return #t
(eq? "Another lorem" (match-key test-lst 'title)) ; should return #f
(eq? 999.99 (match-key test-lst 'price)) ; should return #t
(eq? 111.11 (match-key test-lst 'price)) ; should return #f
答案 0 :(得分:3)
在结构上,模式(list key val)
与(list (list key val) ...)
不同。由于您将后者作为字典的结构,因此在过程match-key
中匹配的唯一子句将成为最后一个,其中_
表示与任何语法对象匹配的模式。
要使用match
过滤键值对列表并返回所有关联值,您可以执行以下操作:
(define (filter/match lst key)
(let ([has-key? (lambda (l) (equal? (car l) key))])
(match lst
['() '()]
[(cons (? has-key?) b) (cons (cadar lst) (filter/match b key))]
[(cons a b) (filter/match b key)])))
例如,
;; test data
(define test-lst
(list (list 'title "title1")
(list 'price 999.99)
(list 'title "title2")
(list 'colour "red")))
(filter/match test-lst 'title)
=> '("title1" "title2")
或者,您可以使用for/list
更简单地实现此目的,如下所示:
(define (get-val lst key)
(for/list ([l lst]
#:when (equal? (car l) key))
(cadr l)))
例如:
> (get-val test-lst 'title)
'("title1" "title2")
您还可以查看可用于dictionaries的各种内置程序。例如,使用dict-ref
,您可以执行以下操作:
(dict-ref test-lst 'title #f)
=> '("title1")
(dict-ref test-lst 'rand-key #f)
=> #f
这将返回第一个键实例的值(因此,与键关联的所有值都不匹配)。如果未找到任何匹配项,则返回#f
。