Add the ability to remove keys from a hash table.
This commit is contained in:
parent
a2a5532703
commit
99da463f84
|
|
@ -82,4 +82,40 @@
|
|||
(hash-table-node-right-child-set! node
|
||||
(make-hash-table-node hash key val))))]))))))
|
||||
|
||||
(define (hash-table-remove ht key [not-found (lambda () #f)])
|
||||
(let ([hash ((hash-table-hash-function ht) key)]
|
||||
[eq-fn (hash-table-eq-function ht)])
|
||||
(let search ([node (hash-table-root-node ht)]
|
||||
[replace-node! (lambda (n) (hash-table-root-node-set! ht n))])
|
||||
(if node
|
||||
(let ([node-hash (hash-table-node-hash node)])
|
||||
(cond
|
||||
[(and (fix= hash node-hash)
|
||||
(eq-fn (hash-table-node-key node) key))
|
||||
(let ([oldval (hash-table-node-value node)]
|
||||
[left (hash-table-node-left-child node)]
|
||||
[right (hash-table-node-right-child node)])
|
||||
(cond
|
||||
[(not left) (replace-node! right)]
|
||||
[(not right) (replace-node! left)]
|
||||
[else
|
||||
(let find-leftmost ([parent node] [lnode right])
|
||||
(let ([lc (hash-table-node-left-child lnode)])
|
||||
(if lc
|
||||
(find-leftmost lnode lc)
|
||||
(let ([rc (hash-table-node-right-child lnode)])
|
||||
(hash-table-node-left-child-set! parent rc)
|
||||
(hash-table-node-left-child-set! lnode left)
|
||||
(unless (eq? lnode right)
|
||||
(hash-table-node-right-child-set! lnode right))
|
||||
(replace-node! lnode)))))])
|
||||
oldval)]
|
||||
[(fix<= hash node-hash)
|
||||
(search (hash-table-node-left-child node)
|
||||
(lambda (n) (hash-table-node-left-child-set! node n)))]
|
||||
[else
|
||||
(search (hash-table-node-right-child node)
|
||||
(lambda (n) (hash-table-node-right-child-set! node n)))]))
|
||||
(not-found)))))
|
||||
|
||||
; vim:set syntax=scheme sw=2 expandtab:
|
||||
|
|
|
|||
|
|
@ -3,15 +3,29 @@
|
|||
|
||||
(define ht (make-hash-table))
|
||||
|
||||
(hash-table-insert ht "test" 5)
|
||||
(hash-table-insert ht "a longer key" '(4 5 6))
|
||||
(hash-table-insert ht '(9 8 7) "backwards")
|
||||
(define (foreach fn lst)
|
||||
(when (pair? lst)
|
||||
(fn (car lst))
|
||||
(foreach fn (cdr lst))))
|
||||
|
||||
(let ([insert (lambda (x) (hash-table-insert ht x x))])
|
||||
(foreach insert '(47 32 18 90 46 38 21 93 49 10 92 34 71)))
|
||||
|
||||
(values
|
||||
(hash-table-lookup ht "test")
|
||||
(hash-table-lookup ht "no such key")
|
||||
(hash-table-lookup ht "a longer key")
|
||||
(hash-table-lookup ht '(7 8 9))
|
||||
(hash-table-lookup ht '(9 8 7)))
|
||||
(hash-table-remove ht 92)
|
||||
(hash-table-remove ht 71)
|
||||
(hash-table-remove ht 49)
|
||||
(hash-table-remove ht 46)
|
||||
(hash-table-remove ht 47)
|
||||
(hash-table-remove ht 21)
|
||||
(hash-table-remove ht 30)
|
||||
(hash-table-remove ht 34)
|
||||
(hash-table-remove ht 18)
|
||||
(hash-table-remove ht 32)
|
||||
(hash-table-remove ht 90)
|
||||
(hash-table-remove ht 10)
|
||||
(hash-table-remove ht 38)
|
||||
(hash-table-remove ht 93)
|
||||
)
|
||||
|
||||
; vim:set syntax=scheme sw=2 expandtab:
|
||||
|
|
|
|||
Loading…
Reference in New Issue