Move contents of unstable/hash to racket/hash.
This commit is contained in:
parent
952df81877
commit
7700b3d736
|
@ -496,3 +496,71 @@ inspectable structure fields. See also @racket[gen:equal+hash].}
|
|||
|
||||
Like @racket[equal-hash-code], but computes a secondary value suitable
|
||||
for use in double hashing.}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Additional Hash Table Functions}
|
||||
|
||||
@note-lib-only[racket/hash]
|
||||
|
||||
@(define the-eval (make-base-eval))
|
||||
@(the-eval '(require racket/hash))
|
||||
|
||||
@defproc[(hash-union [h0 (and/c hash? hash-can-functional-set?)]
|
||||
[h hash?] ...
|
||||
[#:combine combine
|
||||
(-> any/c any/c any/c)
|
||||
(lambda _ (error 'hash-union ....))]
|
||||
[#:combine/key combine/key
|
||||
(-> any/c any/c any/c any/c)
|
||||
(lambda (k a b) (combine a b))])
|
||||
(and/c hash? hash-can-functional-set?)]{
|
||||
|
||||
Computes the union of @racket[h0] with each hash table @racket[h] by functional
|
||||
update, adding each element of each @racket[h] to @racket[h0] in turn. For each
|
||||
key @racket[k] and value @racket[v], if a mapping from @racket[k] to some value
|
||||
@racket[v0] already exists, it is replaced with a mapping from @racket[k] to
|
||||
@racket[(combine/key k v0 v)].
|
||||
|
||||
@defexamples[
|
||||
#:eval the-eval
|
||||
(hash-union (make-immutable-hash '([1 . one]))
|
||||
(make-immutable-hash '([2 . two]))
|
||||
(make-immutable-hash '([3 . three])))
|
||||
(hash-union (make-immutable-hash '([1 . (one uno)] [2 . (two dos)]))
|
||||
(make-immutable-hash '([1 . (ein une)] [2 . (zwei deux)]))
|
||||
#:combine/key (lambda (k v1 v2) (append v1 v2)))
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@defproc[(hash-union! [h0 (and/c hash? hash-mutable?)]
|
||||
[h hash?] ...
|
||||
[#:combine combine
|
||||
(-> any/c any/c any/c)
|
||||
(lambda _ (error 'hash-union ....))]
|
||||
[#:combine/key combine/key
|
||||
(-> any/c any/c any/c any/c)
|
||||
(lambda (k a b) (combine a b))])
|
||||
void?]{
|
||||
|
||||
Computes the union of @racket[h0] with each hash table @racket[h] by mutable
|
||||
update, adding each element of each @racket[h] to @racket[h0] in turn. For each
|
||||
key @racket[k] and value @racket[v], if a mapping from @racket[k] to some value
|
||||
@racket[v0] already exists, it is replaced with a mapping from @racket[k] to
|
||||
@racket[(combine/key k v0 v)].
|
||||
|
||||
@defexamples[
|
||||
#:eval the-eval
|
||||
(define h (make-hash))
|
||||
h
|
||||
(hash-union! h (make-immutable-hash '([1 . (one uno)] [2 . (two dos)])))
|
||||
h
|
||||
(hash-union! h
|
||||
(make-immutable-hash '([1 . (ein une)] [2 . (zwei deux)]))
|
||||
#:combine/key (lambda (k v1 v2) (append v1 v2)))
|
||||
h
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@(close-eval the-eval)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(load-in-sandbox "list.rktl")
|
||||
(load-in-sandbox "math.rktl")
|
||||
(load-in-sandbox "vector.rktl")
|
||||
(load-in-sandbox "hash.rktl")
|
||||
(load-in-sandbox "function.rktl")
|
||||
(load-in-sandbox "dict.rktl")
|
||||
(load-in-sandbox "fixnum.rktl")
|
||||
|
|
36
pkgs/racket-test-core/tests/racket/hash.rktl
Normal file
36
pkgs/racket-test-core/tests/racket/hash.rktl
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
(load-relative "loadtest.rktl")
|
||||
|
||||
(Section 'hash)
|
||||
|
||||
(require racket/hash)
|
||||
|
||||
(test #hash([4 . four] [3 . three] [1 . one] [2 . two])
|
||||
hash-union #hash([1 . one] [2 . two]) #hash([3 . three] [4 . four]))
|
||||
(test #hash([four . 4] [three . 3] [one . 1] [two . 2])
|
||||
hash-union #hash([one . 1] [two . 1]) #hash([three . 3] [four . 4] [two . 1])
|
||||
#:combine +)
|
||||
|
||||
(let ()
|
||||
(define h (make-hash))
|
||||
(hash-union! h #hash([1 . one] [2 . two]))
|
||||
(hash-union! h #hash([3 . three] [4 . four]))
|
||||
(test #t
|
||||
equal?
|
||||
(hash-copy
|
||||
#hash([1 . one] [2 . two] [3 . three] [4 . four]))
|
||||
h))
|
||||
(let ()
|
||||
(define h (make-hash))
|
||||
(hash-union! h #hash([one . 1] [two . 1]))
|
||||
(err/rt-test (hash-union! h #hash([three . 3] [four . 4] [two . 1])) exn:fail?))
|
||||
(let ()
|
||||
(define h (make-hash))
|
||||
(hash-union! h #hash([one . 1] [two . 1]))
|
||||
(hash-union! h #hash([three . 3] [four . 4] [two . 1])
|
||||
#:combine/key (lambda (k x y) (+ x y)))
|
||||
(test #t
|
||||
equal?
|
||||
(hash-copy
|
||||
#hash([one . 1] [two . 2] [three . 3] [four . 4]))
|
||||
h))
|
45
racket/collects/racket/hash.rkt
Normal file
45
racket/collects/racket/hash.rkt
Normal file
|
@ -0,0 +1,45 @@
|
|||
#lang racket/base
|
||||
(require racket/contract/base)
|
||||
|
||||
(define ((hash-duplicate-error name) key value1 value2)
|
||||
(error name "duplicate values for key ~e: ~e and ~e" key value1 value2))
|
||||
|
||||
(define (hash-union
|
||||
#:combine [combine #f]
|
||||
#:combine/key [combine/key
|
||||
(if combine
|
||||
(lambda (k x y) (combine x y))
|
||||
(hash-duplicate-error 'hash-union))]
|
||||
one . rest)
|
||||
(for*/fold ([one one]) ([two (in-list rest)] [(k v) (in-hash two)])
|
||||
(hash-set one k (if (hash-has-key? one k)
|
||||
(combine/key k (hash-ref one k) v)
|
||||
v))))
|
||||
|
||||
(define (hash-union!
|
||||
#:combine [combine #f]
|
||||
#:combine/key [combine/key
|
||||
(if combine
|
||||
(lambda (k x y) (combine x y))
|
||||
(hash-duplicate-error 'hash-union))]
|
||||
one . rest)
|
||||
(for* ([two (in-list rest)] [(k v) (in-hash two)])
|
||||
(hash-set! one k (if (hash-has-key? one k)
|
||||
(combine/key k (hash-ref one k) v)
|
||||
v))))
|
||||
|
||||
(provide/contract
|
||||
[hash-union (->* [(and/c hash? immutable?)]
|
||||
[#:combine
|
||||
(-> any/c any/c any/c)
|
||||
#:combine/key
|
||||
(-> any/c any/c any/c any/c)]
|
||||
#:rest (listof hash?)
|
||||
(and/c hash? immutable?))]
|
||||
[hash-union! (->* [(and/c hash? (not/c immutable?))]
|
||||
[#:combine
|
||||
(-> any/c any/c any/c)
|
||||
#:combine/key
|
||||
(-> any/c any/c any/c any/c)]
|
||||
#:rest (listof hash?)
|
||||
void?)])
|
Loading…
Reference in New Issue
Block a user