(module hash-table mzscheme
(require (lib "etc.ss")
(lib "string.ss" "srfi" "13")
(file "base.ss")
(file "list.ss"))
(provide (all-defined))
(define (make-hash-table/pairs . pairs)
(let ([table (make-hash-table)])
(alist-for-each
(lambda (key value)
(hash-table-put! table key value))
pairs)
table))
(define (hash-table-mapped? table key)
(with-handlers ([exn:unlib? (lambda (exn) #f)])
(hash-table-get table key (lambda () (raise-exn exn:unlib "Not found.")))
#t))
(define (hash-table-get/default table key default)
(hash-table-get table key (lambda () default)))
(define (hash-table-accessor table)
(lambda (key)
(hash-table-get
table
key
(lambda ()
(raise-exn exn:fail:unlib
(format "Key not found in hash-table: ~a" key))))))
(define (hash-table-accessor/default table default)
(lambda (key)
(hash-table-get/default
table
key
default)))
(define (hash-table-put/append! table key value)
(let ([values (hash-table-get table key (lambda () null))])
(if (list? values)
(hash-table-put! table key (append values (list value)))
(raise-exn exn:fail:unlib
(format "Key not mapped to list: ~a ~a" key values)))))
(define (hash-table-mutator table)
(lambda (key value)
(hash-table-put! table key value)))
(define (hash-table-mutator/append table)
(lambda (key value)
(hash-table-put/append! table key value)))
(define hash-table-find
(opt-lambda (table selector [default (lambda () #f)])
(let ([ans #f])
(with-handlers
([exn:unlib?
(lambda (exn)
ans)])
(hash-table-for-each
table
(lambda (key val)
(let ([match (selector key val)])
(if match
(set! ans match)
(raise-exn exn:unlib "")))))
(default)))))
(define (any-keys-have-values? table)
(with-handlers ([exn:unlib? (lambda (exn) #t)])
(hash-table-for-each
table
(lambda (key values)
(if (list? values)
(if (not (null? values))
(raise-exn exn:unlib
"Breaking from for-each."))
(raise-exn exn:fail:unlib
(format "Key not mapped to a list: ~a ~a" key values)))))
#f))
(define (key-has-values? table key)
(let ([values (hash-table-get table key (lambda () null))])
(if (list? values)
(not (null? values))
(raise-exn exn:fail:unlib
(format "Key not mapped to a list: ~a ~a" key values)))))
(define hash-table->string
(opt-lambda (table [delimiter ", "])
(string-join
(hash-table-map
table
(lambda (key value)
(format "~a=~a" key value)))
delimiter)))
)