utils: Add hash-filter.
This commit is contained in:
parent
208dc12060
commit
73756d8974
1 changed files with 34 additions and 1 deletions
35
utils.rkt
35
utils.rkt
|
@ -55,7 +55,11 @@
|
||||||
[#:combine (-> any/c any/c any/c)
|
[#:combine (-> any/c any/c any/c)
|
||||||
#:combine/key (-> any/c any/c any/c any/c)]
|
#:combine/key (-> any/c any/c any/c any/c)]
|
||||||
#:rest (listof hash?)
|
#:rest (listof hash?)
|
||||||
(and/c hash? immutable?))])
|
(and/c hash? immutable?))]
|
||||||
|
[hash-filter (->* (hash?)
|
||||||
|
(#:predicate (-> any/c boolean?)
|
||||||
|
#:predicate/key (-> any/c any/c boolean?))
|
||||||
|
hash?)])
|
||||||
;; Contracts
|
;; Contracts
|
||||||
(contract-out [variable-mapping? contract?]
|
(contract-out [variable-mapping? contract?]
|
||||||
[string-variable-mapping? contract?]
|
[string-variable-mapping? contract?]
|
||||||
|
@ -624,6 +628,35 @@
|
||||||
(check-equal? (hash-intersect h1 h3 #:combine -)
|
(check-equal? (hash-intersect h1 h3 #:combine -)
|
||||||
'#hash((a . -6) (c . -5)))))
|
'#hash((a . -6) (c . -5)))))
|
||||||
|
|
||||||
|
;;; Functionally filters a hash table: only keeps the key-value pairs
|
||||||
|
;;; that satisfy a given criterion.
|
||||||
|
;;;
|
||||||
|
;;; The filtering criterion should be specified either via #:predicate
|
||||||
|
;;; or #:predicate/key. #:predicate should be a function returning
|
||||||
|
;;; a Boolean result given a value of the hash value. #:predicate
|
||||||
|
;;; should be a function taking a key and the corresponding value.
|
||||||
|
(define (hash-filter
|
||||||
|
ht
|
||||||
|
#:predicate [predicate #f]
|
||||||
|
#:predicate/key [predicate/key
|
||||||
|
(if predicate
|
||||||
|
(λ (_ v) (predicate v))
|
||||||
|
(error 'hash-filter))])
|
||||||
|
(for/fold ([filtered-pairs (hash-clear ht)])
|
||||||
|
([(k v) (in-hash ht)])
|
||||||
|
(if (predicate/key k v)
|
||||||
|
(hash-set filtered-pairs k v)
|
||||||
|
filtered-pairs)))
|
||||||
|
|
||||||
|
(module+ test
|
||||||
|
(test-case "hash-filter"
|
||||||
|
(check-equal? (hash-filter (hash 'a 0 'b 1 'c 0)
|
||||||
|
#:predicate (compose not zero?))
|
||||||
|
#hash((b . 1)))
|
||||||
|
(check-equal? (hash-filter (hash 'a 0 'b 1 'c 0) #:predicate/key
|
||||||
|
(λ (k v) (and (eq? k 'b) (not (zero? v)))))
|
||||||
|
'#hash((b . 1)))))
|
||||||
|
|
||||||
;;; =========
|
;;; =========
|
||||||
;;; Functions
|
;;; Functions
|
||||||
;;; =========
|
;;; =========
|
||||||
|
|
Loading…
Reference in a new issue