2017-04-27 50 views
2

相關的所有值我有一個列表像(列表(列表鍵值)...),我試圖建立一個函數返回與鍵相關的所有值。racket:我試圖建立一個函數,返回與鍵

我想我可以使用匹配構造來做到這一點,但沒有任何成功。

#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 

回答

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

相關問題