我正在尝试用相应的值替换等于散列映射键的列表元素。
这是我尝试过的:
#lang racket
(define my-hash (make-hash))
(hash-set! my-hash 'a 1)
(hash-set! my-hash 'b 2)
(hash-set! my-hash 'c 3)
(define (replace-all ht lst)
(hash-map ht
(lambda (key value)
(convert-list key value lst)))
)
(define (convert-list old_element new_element lst)
(cond [(equal? lst '()) '()]
[(not (list? lst)) (if (equal? old_element lst) new_element lst)]
[(list? (car lst)) (cons (convert-list old_element new_element (car lst)) (convert-list old_element new_element (cdr lst)))]
[else (if (equal? old_element (car lst)) (cons new_element (convert-list old_element new_element (cdr lst)))
(cons (car lst) (convert-list old_element new_element (cdr lst))))]
)
)
(replace-all my-hash '(a b c d '(a b)))
给了我'((a b 3 d '(a b)) (1 b c d '(1 b)) (a 2 c d '(a 2)))
。我想要的是'(1 2 3 d'(1 2))
。我应该怎么做?
您正在向后工作 - 而不是遍历表并尝试依次替换它的每个键,而是遍历嵌套列表并替换表中存在的元素。例如:
#lang racket
; Consider using hasheq instead if your keys are always going to be symbols
(define my-hash #hash((a . 1) (b . 2) (c . 3)))
(define (replace-all ht lst)
(cond
((hash-has-key? ht lst) ; Current lst is a key that exists in the hash table
; So return the value
(hash-ref ht lst))
((pair? lst) ; Current lst is a cons cell (Not list? so it works with improper lists too)
; Recurse on both the car and cdr and return a new pair
(cons (replace-all ht (car lst)) (replace-all ht (cdr lst))))
(else ; No match and it's an atom; return it.
lst)))
(replace-all my-hash '(a b c d '(a b)))
你的方法还不错。如果你会使用:
(define (replace-all ht lst)
(define (replace-elem elem)
(cond ((list? elem) (map replace-elem elem))
((hash-has-key? ht elem) (hash-ref ht elem))
(else elem)))
(map replace-elem lst))
你得到:
> (replace-all my-hash '(a b c d '(a b)))
'(1 2 3 d '(1 2))