4.10 Multidicts
(require rebellion/collection/multidict) | |
package: rebellion |
A multidict is an unordered collection of key-value mappings, where multiple unique values for the same key are allowed. The implementation of multidicts behaves similarly to a hash from keys to nonempty sets, but the interface is based on a flattened collection of key-value pairs.
procedure
(multidict? v) → boolean?
v : any/c
procedure
(multidict k v ... ...) → multidict?
k : any/c v : any/c
> (multidict 'a 1 'b 2 'c 3) (multidict 'a 1 'c 3 'b 2)
> (multidict 'a 1 'a 2 'a 3) (multidict 'a 1 'a 3 'a 2)
> (multidict 'a 1 'a 1 'b 1) (multidict 'a 1 'b 1)
value
procedure
(empty-multidict? v) → boolean?
v : any/c
procedure
(nonempty-multidict? v) → boolean?
v : any/c
4.10.1 Persistently Updating Multidicts
procedure
(multidict-add dict k v) → multidict?
dict : multidict? k : any/c v : any/c
> (multidict-add (multidict 'a 1) 'b 2) (multidict 'a 1 'b 2)
> (multidict-add (multidict 'a 1) 'a 2) (multidict 'a 1 'a 2)
> (multidict-add (multidict 'a 1) 'a 1) (multidict 'a 1)
procedure
(multidict-add-entry dict e) → multidict?
dict : multidict? e : entry?
> (multidict-add-entry (multidict 'a 1) (entry 'b 2)) (multidict 'a 1 'b 2)
> (multidict-add-entry (multidict 'a 1) (entry 'a 2)) (multidict 'a 1 'a 2)
> (multidict-add-entry (multidict 'a 1) (entry 'a 1)) (multidict 'a 1)
procedure
(multidict-remove dict k v) → multidict?
dict : multidict? k : any/c v : any/c
> (multidict-remove (multidict 'a 1 'a 2) 'a 1) (multidict 'a 2)
> (multidict-remove (multidict 'a 1 'a 2) 'b 1) (multidict 'a 1 'a 2)
procedure
(multidict-remove-entry dict e) → multidict?
dict : multidict? e : entry?
> (multidict-remove-entry (multidict 'a 1 'a 2) (entry 'a 1)) (multidict 'a 2)
> (multidict-remove-entry (multidict 'a 1 'a 2) (entry 'b 1)) (multidict 'a 1 'a 2)
procedure
(multidict-replace-values dict k vs) → multidict?
dict : multidict? k : any/c vs : (sequence/c any/c)
> (define dict (multidict 'a 1 'b 2 'b 3)) > (multidict-replace-values dict 'a (in-range 1 5)) (multidict 'a 1 'a 3 'a 2 'a 4 'b 3 'b 2)
> (multidict-replace-values dict 'b empty-list) (multidict 'a 1)
> (multidict-replace-values dict 'c "hello") (multidict 'a 1 'c #\o 'c #\l 'c #\h 'c #\e 'b 3 'b 2)
4.10.2 Querying Multidicts
procedure
(multidict-size dict) → natural?
dict : multidict?
> (multidict-size (multidict 'a 1 'b 2 'c 3)) 3
> (multidict-size (multidict 'a 1 'b 2 'b 3)) 3
> (multidict-size (multidict 'a 1 'a 1 'a 1)) 1
procedure
(multidict-ref dict k) → set?
dict : multidict? k : any/c
> (define dict (multidict 'fruit 'apple 'fruit 'orange 'fruit 'banana 'vegetable 'carrot 'vegetable 'celery)) > (multidict-ref dict 'fruit) (set 'apple 'banana 'orange)
> (multidict-ref dict 'vegetable) (set 'celery 'carrot)
> (multidict-ref dict 'dessert) (set)
procedure
(multidict-keys dict) → multiset?
dict : multidict?
> (multidict-keys (multidict 'fruit 'apple 'fruit 'orange 'fruit 'banana 'vegetable 'carrot 'vegetable 'celery)) (multiset 'vegetable 'vegetable 'fruit 'fruit 'fruit)
procedure
(multidict-values dict) → multiset?
dict : multidict?
> (multidict-values (multidict "Iron Man" 'marvel "Superman" 'dc "The Black Panther" 'marvel "Wonder Woman" 'dc "The Hulk" 'marvel "Captain Marvel" 'marvel)) (multiset 'dc 'dc 'marvel 'marvel 'marvel 'marvel)
procedure
(multidict-unique-keys dict) → set?
dict : multidict?
> (multidict-unique-keys (multidict 'fruit 'apple 'fruit 'orange 'fruit 'banana 'vegetable 'carrot 'vegetable 'celery)) (set 'vegetable 'fruit)
procedure
(multidict-unique-values dict) → set?
dict : multidict?
> (multidict-unique-values (multidict "Iron Man" 'marvel "Superman" 'dc "The Black Panther" 'marvel "Wonder Woman" 'dc "The Hulk" 'marvel "Captain Marvel" 'marvel)) (set 'dc 'marvel)
procedure
(multidict-entries dict) → (set/c entry?)
dict : multidict?
> (multidict-entries (multidict 'fruit 'apple 'fruit 'orange 'fruit 'banana 'vegetable 'carrot 'vegetable 'celery))
(set
(entry 'vegetable 'celery)
(entry 'vegetable 'carrot)
(entry 'fruit 'orange)
(entry 'fruit 'banana)
(entry 'fruit 'apple))
procedure
(multidict-inverse dict) → multidict?
dict : multidict?
> (multidict-inverse (multidict 'a 1 'a 2 'a 3 'b 2 'b 4 'c 4 'c 1 'd 3)) (multidict 1 'a 1 'c 3 'a 3 'd 2 'a 2 'b 4 'c 4 'b)
procedure
(multidict-contains-key? dict k) → boolean?
dict : multidict? k : any/c
> (define dict (multidict 'even 2 'even 4 'odd 1 'odd 5 'odd 3)) > (multidict-contains-key? dict 'even) #t
> (multidict-contains-key? dict 'prime) #f
procedure
(multidict-contains-value? dict v) → boolean?
dict : multidict? v : any/c
> (define dict (multidict 'even 2 'even 4 'odd 1 'odd 5 'odd 3)) > (multidict-contains-value? dict 5) #t
> (multidict-contains-value? dict "hello world") #f
procedure
(multidict-contains-entry? dict e) → boolean?
dict : multidict? e : entry?
> (define dict (multidict 'even 2 'even 4 'odd 1 'odd 5 'odd 3)) > (multidict-contains-entry? dict (entry 'even 4)) #t
> (multidict-contains-entry? dict (entry 'odd 4)) #f
4.10.3 Multidict Conversions
procedure
(multidict->hash dict)
→ (hash/c any/c nonempty-set? #:immutable #t) dict : multidict?
> (multidict->hash (multidict 'fruit 'apple 'fruit 'orange 'fruit 'banana 'vegetable 'carrot 'vegetable 'celery)) (hash 'fruit (set 'apple 'banana 'orange) 'vegetable (set 'celery 'carrot))
4.10.4 Multidict Iterations and Comprehensions
procedure
(in-multidict-entries dict) → (sequence/c entry?)
dict : multidict?
> (define food-classifications (multidict 'fruit 'apple 'vegetable 'carrot 'fruit 'orange 'fruit 'banana 'vegetable 'celery))
> (for ([e (in-multidict-entries food-classifications)]) (printf "key: ~a value: ~a\n" (entry-key e) (entry-value e)))
key: vegetable value: celery
key: vegetable value: carrot
key: fruit value: apple
key: fruit value: banana
key: fruit value: orange
syntax
(for/multidict (for-clause ...) body-or-break ... body)
body : entry?
syntax
(for*/multidict (for-clause ...) body-or-break ... body)
body : entry?
value