hamster 1.0.0 → 1.0.1.pre.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hamster.rb +2 -3
- data/lib/hamster/core_ext.rb +1 -0
- data/lib/hamster/core_ext/enumerable.rb +17 -17
- data/lib/hamster/core_ext/enumerator.rb +16 -0
- data/lib/hamster/core_ext/io.rb +17 -15
- data/lib/hamster/enumerable.rb +107 -123
- data/lib/hamster/experimental/mutable_queue.rb +6 -2
- data/lib/hamster/experimental/mutable_set.rb +3 -1
- data/lib/hamster/experimental/mutable_stack.rb +30 -0
- data/lib/hamster/hash.rb +95 -713
- data/lib/hamster/immutable.rb +0 -4
- data/lib/hamster/list.rb +242 -1062
- data/lib/hamster/mutable_hash.rb +3 -1
- data/lib/hamster/queue.rb +87 -0
- data/lib/hamster/read_copy_update.rb +1 -2
- data/lib/hamster/set.rb +73 -478
- data/lib/hamster/sorter.rb +25 -0
- data/lib/hamster/stack.rb +75 -0
- data/lib/hamster/trie.rb +48 -199
- data/lib/hamster/tuple.rb +39 -0
- data/lib/hamster/undefined.rb +3 -1
- data/lib/hamster/vector.rb +72 -1326
- data/lib/hamster/version.rb +1 -1
- data/spec/hamster/core_ext/array_spec.rb +20 -0
- data/spec/{lib/hamster → hamster}/core_ext/enumerable_spec.rb +0 -5
- data/spec/hamster/core_ext/enumerator_spec.rb +19 -0
- data/spec/{lib/hamster → hamster}/core_ext/io_spec.rb +0 -0
- data/spec/hamster/experimental/mutable_set/add_qm_spec.rb +47 -0
- data/spec/hamster/experimental/mutable_set/add_spec.rb +51 -0
- data/spec/hamster/experimental/mutable_set/delete_qm_spec.rb +47 -0
- data/spec/hamster/experimental/mutable_set/delete_spec.rb +47 -0
- data/spec/hamster/experimental/mutable_stack/pop_spec.rb +41 -0
- data/spec/hamster/experimental/mutable_stack/push_spec.rb +41 -0
- data/spec/hamster/hash/all_spec.rb +59 -0
- data/spec/hamster/hash/any_spec.rb +67 -0
- data/spec/hamster/hash/clear_spec.rb +36 -0
- data/spec/hamster/hash/construction_spec.rb +35 -0
- data/spec/{lib/hamster → hamster}/hash/copying_spec.rb +12 -3
- data/spec/hamster/hash/delete_spec.rb +47 -0
- data/spec/hamster/hash/each_spec.rb +41 -0
- data/spec/hamster/hash/empty_spec.rb +27 -0
- data/spec/hamster/hash/eql_spec.rb +62 -0
- data/spec/hamster/hash/except_spec.rb +31 -0
- data/spec/hamster/hash/fetch_spec.rb +95 -0
- data/spec/hamster/hash/filter_spec.rb +63 -0
- data/spec/hamster/hash/find_spec.rb +58 -0
- data/spec/hamster/hash/get_spec.rb +55 -0
- data/spec/hamster/hash/has_key_spec.rb +35 -0
- data/spec/hamster/hash/hash_spec.rb +52 -0
- data/spec/{lib/hamster → hamster}/hash/immutable_spec.rb +3 -0
- data/spec/hamster/hash/inspect_spec.rb +32 -0
- data/spec/hamster/hash/keys_spec.rb +21 -0
- data/spec/hamster/hash/map_spec.rb +64 -0
- data/spec/{lib/hamster → hamster}/hash/marshal_spec.rb +3 -3
- data/spec/hamster/hash/merge_spec.rb +36 -0
- data/spec/{lib/hamster → hamster}/hash/none_spec.rb +14 -12
- data/spec/hamster/hash/put_spec.rb +65 -0
- data/spec/hamster/hash/reduce_spec.rb +60 -0
- data/spec/hamster/hash/remove_spec.rb +63 -0
- data/spec/{lib/hamster → hamster}/hash/size_spec.rb +2 -2
- data/spec/hamster/hash/slice_spec.rb +26 -0
- data/spec/hamster/hash/uniq_spec.rb +23 -0
- data/spec/hamster/hash/values_spec.rb +34 -0
- data/spec/{lib/hamster → hamster}/immutable/copying_spec.rb +8 -1
- data/spec/{lib/hamster → hamster}/immutable/immutable_spec.rb +14 -1
- data/spec/{lib/hamster → hamster}/immutable/memoize_spec.rb +3 -2
- data/spec/{lib/hamster → hamster}/immutable/new_spec.rb +0 -0
- data/spec/{lib/hamster → hamster}/immutable/transform_spec.rb +0 -0
- data/spec/{lib/hamster → hamster}/immutable/transform_unless_spec.rb +0 -0
- data/spec/hamster/list/add_spec.rb +16 -0
- data/spec/hamster/list/all_spec.rb +111 -0
- data/spec/hamster/list/any_spec.rb +79 -0
- data/spec/{lib/hamster → hamster}/list/append_spec.rb +22 -11
- data/spec/hamster/list/at_spec.rb +49 -0
- data/spec/hamster/list/break_spec.rb +85 -0
- data/spec/{lib/hamster → hamster}/list/cadr_spec.rb +17 -6
- data/spec/{lib/hamster → hamster}/list/chunk_spec.rb +17 -6
- data/spec/{lib/hamster → hamster}/list/clear_spec.rb +16 -5
- data/spec/hamster/list/combinations_spec.rb +51 -0
- data/spec/{lib/hamster → hamster}/list/compact_spec.rb +17 -6
- data/spec/hamster/list/cons_spec.rb +41 -0
- data/spec/hamster/list/construction_spec.rb +166 -0
- data/spec/{lib/hamster → hamster}/list/copying_spec.rb +16 -4
- data/spec/hamster/list/count_spec.rb +66 -0
- data/spec/hamster/list/cycle_spec.rb +45 -0
- data/spec/{lib/hamster → hamster}/list/drop_spec.rb +17 -6
- data/spec/hamster/list/drop_while_spec.rb +59 -0
- data/spec/hamster/list/each_slice_spec.rb +80 -0
- data/spec/hamster/list/each_spec.rb +72 -0
- data/spec/hamster/list/each_with_index_spec.rb +42 -0
- data/spec/hamster/list/elem_index_spec.rb +58 -0
- data/spec/hamster/list/elem_indices_spec.rb +45 -0
- data/spec/hamster/list/empty_spec.rb +47 -0
- data/spec/hamster/list/eql_spec.rb +78 -0
- data/spec/hamster/list/filter_spec.rb +70 -0
- data/spec/{lib/hamster → hamster}/list/find_all_spec.rb +2 -3
- data/spec/{lib/hamster → hamster}/list/find_index_spec.rb +27 -5
- data/spec/hamster/list/find_indices_spec.rb +45 -0
- data/spec/{lib/hamster → hamster}/list/find_spec.rb +33 -11
- data/spec/{lib/hamster → hamster}/list/flat_map_spec.rb +0 -0
- data/spec/{lib/hamster → hamster}/list/flatten_spec.rb +17 -6
- data/spec/{lib/hamster → hamster}/list/grep_spec.rb +33 -10
- data/spec/{lib/hamster → hamster}/list/group_by_spec.rb +44 -9
- data/spec/{lib/hamster → hamster}/list/hash_spec.rb +12 -4
- data/spec/{lib/hamster → hamster}/list/head_spec.rb +18 -3
- data/spec/{lib/hamster → hamster}/list/include_spec.rb +27 -6
- data/spec/{lib/hamster → hamster}/list/init_spec.rb +17 -6
- data/spec/hamster/list/inits_spec.rb +42 -0
- data/spec/hamster/list/inspect_spec.rb +43 -0
- data/spec/{lib/hamster → hamster}/list/intersperse_spec.rb +17 -6
- data/spec/hamster/list/join_spec.rb +81 -0
- data/spec/hamster/list/last_spec.rb +44 -0
- data/spec/{lib/hamster → hamster}/list/map_spec.rb +35 -12
- data/spec/hamster/list/maximum_spec.rb +77 -0
- data/spec/{lib/hamster → hamster}/list/merge_by_spec.rb +32 -5
- data/spec/{lib/hamster → hamster}/list/merge_spec.rb +20 -1
- data/spec/hamster/list/minimum_spec.rb +77 -0
- data/spec/{lib/hamster → hamster}/list/none_spec.rb +39 -12
- data/spec/{lib/hamster → hamster}/list/one_spec.rb +38 -13
- data/spec/hamster/list/partition_spec.rb +75 -0
- data/spec/{lib/hamster → hamster}/list/pop_spec.rb +1 -1
- data/spec/hamster/list/product_spec.rb +44 -0
- data/spec/hamster/list/reduce_spec.rb +73 -0
- data/spec/{lib/hamster/list/reject_spec.rb → hamster/list/remove_spec.rb} +35 -11
- data/spec/{lib/hamster → hamster}/list/reverse_spec.rb +25 -8
- data/spec/{lib/hamster → hamster}/list/select_spec.rb +2 -3
- data/spec/{lib/hamster → hamster}/list/size_spec.rb +26 -5
- data/spec/hamster/list/slice_spec.rb +50 -0
- data/spec/{lib/hamster → hamster}/list/sorting_spec.rb +34 -11
- data/spec/hamster/list/span_spec.rb +86 -0
- data/spec/{lib/hamster → hamster}/list/split_at_spec.rb +23 -14
- data/spec/hamster/list/sum_spec.rb +44 -0
- data/spec/hamster/list/tail_spec.rb +48 -0
- data/spec/hamster/list/tails_spec.rb +42 -0
- data/spec/{lib/hamster → hamster}/list/take_spec.rb +17 -6
- data/spec/{lib/hamster → hamster}/list/take_while_spec.rb +18 -11
- data/spec/hamster/list/to_a_spec.rb +54 -0
- data/spec/{lib/hamster → hamster}/list/to_ary_spec.rb +4 -1
- data/spec/{lib/hamster → hamster}/list/to_list_spec.rb +16 -4
- data/spec/hamster/list/to_set_spec.rb +33 -0
- data/spec/{lib/hamster → hamster}/list/union_spec.rb +23 -6
- data/spec/hamster/list/uniq_spec.rb +45 -0
- data/spec/{lib/hamster → hamster}/list/zip_spec.rb +9 -2
- data/spec/hamster/queue/clear_spec.rb +36 -0
- data/spec/hamster/queue/construction_spec.rb +43 -0
- data/spec/hamster/queue/dequeue_spec.rb +40 -0
- data/spec/hamster/queue/empty_spec.rb +47 -0
- data/spec/{lib/hamster/deque → hamster/queue}/enqueue_spec.rb +21 -8
- data/spec/hamster/queue/head_spec.rb +35 -0
- data/spec/hamster/queue/inspect_spec.rb +31 -0
- data/spec/{lib/hamster/deque → hamster/queue}/size_spec.rb +20 -5
- data/spec/hamster/queue/to_a_spec.rb +42 -0
- data/spec/{lib/hamster/deque → hamster/queue}/to_ary_spec.rb +6 -6
- data/spec/hamster/queue/to_list_spec.rb +44 -0
- data/spec/hamster/set/add_spec.rb +51 -0
- data/spec/hamster/set/all_spec.rb +67 -0
- data/spec/hamster/set/any_spec.rb +67 -0
- data/spec/hamster/set/clear_spec.rb +36 -0
- data/spec/{lib/hamster → hamster}/set/compact_spec.rb +16 -5
- data/spec/{lib/hamster → hamster}/set/construction_spec.rb +17 -5
- data/spec/{lib/hamster → hamster}/set/copying_spec.rb +12 -3
- data/spec/{lib/hamster → hamster}/set/count_spec.rb +28 -11
- data/spec/hamster/set/delete_spec.rb +47 -0
- data/spec/{lib/hamster/sorted_set → hamster/set}/difference_spec.rb +21 -7
- data/spec/{lib/hamster/set/reverse_each_spec.rb → hamster/set/each_spec.rb} +7 -8
- data/spec/hamster/set/empty_spec.rb +35 -0
- data/spec/{lib/hamster → hamster}/set/eqeq_spec.rb +0 -0
- data/spec/{lib/hamster → hamster}/set/eql_spec.rb +1 -7
- data/spec/{lib/hamster/sorted_set → hamster/set}/exclusion_spec.rb +20 -5
- data/spec/hamster/set/filter_spec.rb +79 -0
- data/spec/{lib/hamster → hamster}/set/find_spec.rb +25 -8
- data/spec/hamster/set/flatten_spec.rb +49 -0
- data/spec/hamster/set/foreach_spec.rb +39 -0
- data/spec/{lib/hamster → hamster}/set/grep_spec.rb +1 -1
- data/spec/hamster/set/group_by_spec.rb +65 -0
- data/spec/hamster/set/hash_spec.rb +20 -0
- data/spec/hamster/set/head_spec.rb +39 -0
- data/spec/{lib/hamster → hamster}/set/immutable_spec.rb +4 -1
- data/spec/hamster/set/include_spec.rb +35 -0
- data/spec/hamster/set/inspect_spec.rb +32 -0
- data/spec/hamster/set/intersection_spec.rb +46 -0
- data/spec/{lib/hamster/vector → hamster/set}/join_spec.rb +33 -23
- data/spec/hamster/set/map_spec.rb +64 -0
- data/spec/{lib/hamster → hamster}/set/marshal_spec.rb +9 -4
- data/spec/hamster/set/maximum_spec.rb +65 -0
- data/spec/hamster/set/minimum_spec.rb +65 -0
- data/spec/{lib/hamster → hamster}/set/none_spec.rb +30 -15
- data/spec/{lib/hamster → hamster}/set/one_spec.rb +29 -14
- data/spec/hamster/set/partition_spec.rb +71 -0
- data/spec/{lib/hamster → hamster}/set/product_spec.rb +15 -7
- data/spec/hamster/set/reduce_spec.rb +87 -0
- data/spec/hamster/set/remove_spec.rb +63 -0
- data/spec/{lib/hamster → hamster}/set/size_spec.rb +10 -1
- data/spec/{lib/hamster → hamster}/set/sorting_spec.rb +16 -18
- data/spec/hamster/set/subset_spec.rb +39 -0
- data/spec/{lib/hamster/vector → hamster/set}/sum_spec.rb +18 -4
- data/spec/hamster/set/superset_spec.rb +39 -0
- data/spec/hamster/set/to_a_spec.rb +42 -0
- data/spec/{lib/hamster/vector → hamster/set}/to_list_spec.rb +23 -8
- data/spec/{lib/hamster → hamster}/set/to_set_spec.rb +15 -3
- data/spec/hamster/set/union_spec.rb +45 -0
- data/spec/hamster/set/uniq_spec.rb +23 -0
- data/spec/hamster/sorter/immutable_spec.rb +12 -0
- data/spec/hamster/stack/clear_spec.rb +36 -0
- data/spec/hamster/stack/construction_spec.rb +43 -0
- data/spec/hamster/stack/copying_spec.rb +31 -0
- data/spec/hamster/stack/empty_spec.rb +31 -0
- data/spec/hamster/stack/eql_spec.rb +60 -0
- data/spec/hamster/stack/immutable_spec.rb +12 -0
- data/spec/hamster/stack/inspect_spec.rb +31 -0
- data/spec/hamster/stack/peek_spec.rb +40 -0
- data/spec/hamster/stack/pop_spec.rb +41 -0
- data/spec/hamster/stack/push_spec.rb +41 -0
- data/spec/hamster/stack/size_spec.rb +35 -0
- data/spec/hamster/stack/to_a_spec.rb +42 -0
- data/spec/hamster/stack/to_ary.rb +37 -0
- data/spec/hamster/stack/to_list_spec.rb +33 -0
- data/spec/hamster/trie/remove_spec.rb +117 -0
- data/spec/hamster/tuple/copying_spec.rb +24 -0
- data/spec/hamster/tuple/eql_spec.rb +61 -0
- data/spec/hamster/tuple/first_spec.rb +19 -0
- data/spec/hamster/tuple/immutable_spec.rb +12 -0
- data/spec/hamster/tuple/inspect_spec.rb +19 -0
- data/spec/hamster/tuple/last_spec.rb +19 -0
- data/spec/hamster/tuple/to_a_spec.rb +38 -0
- data/spec/hamster/tuple/to_ary_spec.rb +38 -0
- data/spec/hamster/undefined/erase_spec.rb +47 -0
- data/spec/hamster/vector/add_spec.rb +48 -0
- data/spec/{lib/hamster → hamster}/vector/any_spec.rb +0 -0
- data/spec/hamster/vector/clear_spec.rb +35 -0
- data/spec/{lib/hamster → hamster}/vector/copying_spec.rb +14 -4
- data/spec/hamster/vector/each_spec.rb +45 -0
- data/spec/hamster/vector/each_with_index_spec.rb +41 -0
- data/spec/hamster/vector/empty_spec.rb +34 -0
- data/spec/hamster/vector/eql_spec.rb +64 -0
- data/spec/hamster/vector/filter_spec.rb +62 -0
- data/spec/hamster/vector/first_spec.rb +35 -0
- data/spec/hamster/vector/get_spec.rb +80 -0
- data/spec/{lib/hamster → hamster}/vector/include_spec.rb +17 -4
- data/spec/hamster/vector/inspect_spec.rb +33 -0
- data/spec/{lib/hamster → hamster}/vector/last_spec.rb +3 -12
- data/spec/{lib/hamster → hamster}/vector/length_spec.rb +3 -12
- data/spec/hamster/vector/map_spec.rb +63 -0
- data/spec/{lib/hamster → hamster}/vector/reduce_spec.rb +47 -16
- data/spec/hamster/vector/set_spec.rb +113 -0
- data/spec/{lib/hamster → hamster}/vector/to_a_spec.rb +12 -11
- data/spec/{lib/hamster → hamster}/vector/to_ary_spec.rb +0 -0
- data/spec/lib/hamster/vector/cons_spec.rb +48 -0
- data/spec/lib/hamster/vector/exist_spec.rb +70 -0
- data/spec/lib/hamster/vector/exists_spec.rb +70 -0
- data/spec/lib/hamster/vector/ltlt_spec.rb +2 -20
- data/spec/spec_helper.rb +5 -36
- metadata +510 -723
- data/lib/hamster/deque.rb +0 -252
- data/lib/hamster/nested.rb +0 -36
- data/lib/hamster/sorted_set.rb +0 -1397
- data/spec/lib/hamster/core_ext/array_spec.rb +0 -14
- data/spec/lib/hamster/deque/clear_spec.rb +0 -34
- data/spec/lib/hamster/deque/construction_spec.rb +0 -30
- data/spec/lib/hamster/deque/copying_spec.rb +0 -20
- data/spec/lib/hamster/deque/dequeue_spec.rb +0 -35
- data/spec/lib/hamster/deque/empty_spec.rb +0 -40
- data/spec/lib/hamster/deque/first_spec.rb +0 -18
- data/spec/lib/hamster/deque/inspect_spec.rb +0 -24
- data/spec/lib/hamster/deque/last_spec.rb +0 -18
- data/spec/lib/hamster/deque/marshal_spec.rb +0 -34
- data/spec/lib/hamster/deque/new_spec.rb +0 -44
- data/spec/lib/hamster/deque/pop_spec.rb +0 -33
- data/spec/lib/hamster/deque/pretty_print_spec.rb +0 -24
- data/spec/lib/hamster/deque/random_modification_spec.rb +0 -34
- data/spec/lib/hamster/deque/to_a_spec.rb +0 -27
- data/spec/lib/hamster/deque/to_list_spec.rb +0 -26
- data/spec/lib/hamster/deque/unshift_spec.rb +0 -26
- data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +0 -39
- data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +0 -37
- data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +0 -38
- data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +0 -37
- data/spec/lib/hamster/hash/all_spec.rb +0 -54
- data/spec/lib/hamster/hash/any_spec.rb +0 -54
- data/spec/lib/hamster/hash/assoc_spec.rb +0 -52
- data/spec/lib/hamster/hash/clear_spec.rb +0 -43
- data/spec/lib/hamster/hash/construction_spec.rb +0 -39
- data/spec/lib/hamster/hash/default_proc_spec.rb +0 -73
- data/spec/lib/hamster/hash/delete_spec.rb +0 -40
- data/spec/lib/hamster/hash/each_spec.rb +0 -78
- data/spec/lib/hamster/hash/each_with_index_spec.rb +0 -30
- data/spec/lib/hamster/hash/empty_spec.rb +0 -44
- data/spec/lib/hamster/hash/eql_spec.rb +0 -70
- data/spec/lib/hamster/hash/except_spec.rb +0 -43
- data/spec/lib/hamster/hash/fetch_spec.rb +0 -58
- data/spec/lib/hamster/hash/find_spec.rb +0 -44
- data/spec/lib/hamster/hash/flat_map_spec.rb +0 -36
- data/spec/lib/hamster/hash/flatten_spec.rb +0 -99
- data/spec/lib/hamster/hash/get_spec.rb +0 -80
- data/spec/lib/hamster/hash/has_key_spec.rb +0 -32
- data/spec/lib/hamster/hash/has_value_spec.rb +0 -28
- data/spec/lib/hamster/hash/hash_spec.rb +0 -30
- data/spec/lib/hamster/hash/inspect_spec.rb +0 -31
- data/spec/lib/hamster/hash/invert_spec.rb +0 -31
- data/spec/lib/hamster/hash/key_spec.rb +0 -28
- data/spec/lib/hamster/hash/keys_spec.rb +0 -17
- data/spec/lib/hamster/hash/map_spec.rb +0 -46
- data/spec/lib/hamster/hash/merge_spec.rb +0 -83
- data/spec/lib/hamster/hash/min_max_spec.rb +0 -46
- data/spec/lib/hamster/hash/new_spec.rb +0 -71
- data/spec/lib/hamster/hash/partition_spec.rb +0 -36
- data/spec/lib/hamster/hash/pretty_print_spec.rb +0 -35
- data/spec/lib/hamster/hash/put_spec.rb +0 -103
- data/spec/lib/hamster/hash/reduce_spec.rb +0 -36
- data/spec/lib/hamster/hash/reject_spec.rb +0 -62
- data/spec/lib/hamster/hash/reverse_each_spec.rb +0 -28
- data/spec/lib/hamster/hash/sample_spec.rb +0 -14
- data/spec/lib/hamster/hash/select_spec.rb +0 -58
- data/spec/lib/hamster/hash/slice_spec.rb +0 -45
- data/spec/lib/hamster/hash/sort_spec.rb +0 -27
- data/spec/lib/hamster/hash/store_spec.rb +0 -76
- data/spec/lib/hamster/hash/take_spec.rb +0 -36
- data/spec/lib/hamster/hash/to_a_spec.rb +0 -14
- data/spec/lib/hamster/hash/to_hash_spec.rb +0 -22
- data/spec/lib/hamster/hash/update_in_spec.rb +0 -80
- data/spec/lib/hamster/hash/values_at_spec.rb +0 -14
- data/spec/lib/hamster/hash/values_spec.rb +0 -25
- data/spec/lib/hamster/list/add_spec.rb +0 -26
- data/spec/lib/hamster/list/all_spec.rb +0 -58
- data/spec/lib/hamster/list/any_spec.rb +0 -50
- data/spec/lib/hamster/list/at_spec.rb +0 -30
- data/spec/lib/hamster/list/break_spec.rb +0 -70
- data/spec/lib/hamster/list/combination_spec.rb +0 -34
- data/spec/lib/hamster/list/compare_spec.rb +0 -31
- data/spec/lib/hamster/list/cons_spec.rb +0 -26
- data/spec/lib/hamster/list/construction_spec.rb +0 -111
- data/spec/lib/hamster/list/count_spec.rb +0 -37
- data/spec/lib/hamster/list/cycle_spec.rb +0 -29
- data/spec/lib/hamster/list/delete_at_spec.rb +0 -19
- data/spec/lib/hamster/list/delete_spec.rb +0 -17
- data/spec/lib/hamster/list/drop_while_spec.rb +0 -39
- data/spec/lib/hamster/list/each_slice_spec.rb +0 -52
- data/spec/lib/hamster/list/each_spec.rb +0 -41
- data/spec/lib/hamster/list/each_with_index_spec.rb +0 -29
- data/spec/lib/hamster/list/empty_spec.rb +0 -24
- data/spec/lib/hamster/list/eql_spec.rb +0 -62
- data/spec/lib/hamster/list/fill_spec.rb +0 -50
- data/spec/lib/hamster/list/index_spec.rb +0 -34
- data/spec/lib/hamster/list/indices_spec.rb +0 -62
- data/spec/lib/hamster/list/inits_spec.rb +0 -29
- data/spec/lib/hamster/list/insert_spec.rb +0 -47
- data/spec/lib/hamster/list/inspect_spec.rb +0 -30
- data/spec/lib/hamster/list/join_spec.rb +0 -64
- data/spec/lib/hamster/list/last_spec.rb +0 -24
- data/spec/lib/hamster/list/ltlt_spec.rb +0 -20
- data/spec/lib/hamster/list/maximum_spec.rb +0 -40
- data/spec/lib/hamster/list/minimum_spec.rb +0 -40
- data/spec/lib/hamster/list/multithreading_spec.rb +0 -48
- data/spec/lib/hamster/list/partition_spec.rb +0 -116
- data/spec/lib/hamster/list/permutation_spec.rb +0 -56
- data/spec/lib/hamster/list/product_spec.rb +0 -24
- data/spec/lib/hamster/list/reduce_spec.rb +0 -54
- data/spec/lib/hamster/list/rotate_spec.rb +0 -37
- data/spec/lib/hamster/list/sample_spec.rb +0 -14
- data/spec/lib/hamster/list/slice_spec.rb +0 -230
- data/spec/lib/hamster/list/span_spec.rb +0 -77
- data/spec/lib/hamster/list/subsequences_spec.rb +0 -24
- data/spec/lib/hamster/list/sum_spec.rb +0 -24
- data/spec/lib/hamster/list/tail_spec.rb +0 -31
- data/spec/lib/hamster/list/tails_spec.rb +0 -29
- data/spec/lib/hamster/list/to_a_spec.rb +0 -40
- data/spec/lib/hamster/list/to_set_spec.rb +0 -19
- data/spec/lib/hamster/list/transpose_spec.rb +0 -20
- data/spec/lib/hamster/list/uniq_spec.rb +0 -30
- data/spec/lib/hamster/nested/construction_spec.rb +0 -44
- data/spec/lib/hamster/set/add_spec.rb +0 -76
- data/spec/lib/hamster/set/all_spec.rb +0 -52
- data/spec/lib/hamster/set/any_spec.rb +0 -52
- data/spec/lib/hamster/set/clear_spec.rb +0 -34
- data/spec/lib/hamster/set/delete_spec.rb +0 -72
- data/spec/lib/hamster/set/difference_spec.rb +0 -50
- data/spec/lib/hamster/set/disjoint_spec.rb +0 -26
- data/spec/lib/hamster/set/each_spec.rb +0 -46
- data/spec/lib/hamster/set/empty_spec.rb +0 -45
- data/spec/lib/hamster/set/exclusion_spec.rb +0 -48
- data/spec/lib/hamster/set/first_spec.rb +0 -29
- data/spec/lib/hamster/set/flatten_spec.rb +0 -47
- data/spec/lib/hamster/set/group_by_spec.rb +0 -60
- data/spec/lib/hamster/set/hash_spec.rb +0 -23
- data/spec/lib/hamster/set/include_spec.rb +0 -61
- data/spec/lib/hamster/set/inspect_spec.rb +0 -48
- data/spec/lib/hamster/set/intersect_spec.rb +0 -26
- data/spec/lib/hamster/set/intersection_spec.rb +0 -53
- data/spec/lib/hamster/set/join_spec.rb +0 -65
- data/spec/lib/hamster/set/map_spec.rb +0 -60
- data/spec/lib/hamster/set/maximum_spec.rb +0 -37
- data/spec/lib/hamster/set/minimum_spec.rb +0 -37
- data/spec/lib/hamster/set/new_spec.rb +0 -54
- data/spec/lib/hamster/set/partition_spec.rb +0 -53
- data/spec/lib/hamster/set/reduce_spec.rb +0 -56
- data/spec/lib/hamster/set/reject_spec.rb +0 -51
- data/spec/lib/hamster/set/sample_spec.rb +0 -14
- data/spec/lib/hamster/set/select_spec.rb +0 -74
- data/spec/lib/hamster/set/subset_spec.rb +0 -52
- data/spec/lib/hamster/set/sum_spec.rb +0 -24
- data/spec/lib/hamster/set/superset_spec.rb +0 -52
- data/spec/lib/hamster/set/to_a_spec.rb +0 -31
- data/spec/lib/hamster/set/to_list_spec.rb +0 -37
- data/spec/lib/hamster/set/union_spec.rb +0 -64
- data/spec/lib/hamster/sorted_set/above_spec.rb +0 -52
- data/spec/lib/hamster/sorted_set/add_spec.rb +0 -63
- data/spec/lib/hamster/sorted_set/at_spec.rb +0 -25
- data/spec/lib/hamster/sorted_set/below_spec.rb +0 -52
- data/spec/lib/hamster/sorted_set/between_spec.rb +0 -52
- data/spec/lib/hamster/sorted_set/clear_spec.rb +0 -44
- data/spec/lib/hamster/sorted_set/construction_spec.rb +0 -29
- data/spec/lib/hamster/sorted_set/delete_at_spec.rb +0 -19
- data/spec/lib/hamster/sorted_set/delete_spec.rb +0 -90
- data/spec/lib/hamster/sorted_set/disjoint_spec.rb +0 -26
- data/spec/lib/hamster/sorted_set/drop_spec.rb +0 -56
- data/spec/lib/hamster/sorted_set/drop_while_spec.rb +0 -35
- data/spec/lib/hamster/sorted_set/each_spec.rb +0 -29
- data/spec/lib/hamster/sorted_set/empty_spec.rb +0 -35
- data/spec/lib/hamster/sorted_set/eql_spec.rb +0 -121
- data/spec/lib/hamster/sorted_set/fetch_spec.rb +0 -65
- data/spec/lib/hamster/sorted_set/find_index_spec.rb +0 -41
- data/spec/lib/hamster/sorted_set/first_spec.rb +0 -19
- data/spec/lib/hamster/sorted_set/from_spec.rb +0 -52
- data/spec/lib/hamster/sorted_set/group_by_spec.rb +0 -58
- data/spec/lib/hamster/sorted_set/include_spec.rb +0 -24
- data/spec/lib/hamster/sorted_set/inspect_spec.rb +0 -38
- data/spec/lib/hamster/sorted_set/intersect_spec.rb +0 -26
- data/spec/lib/hamster/sorted_set/intersection_spec.rb +0 -29
- data/spec/lib/hamster/sorted_set/last_spec.rb +0 -37
- data/spec/lib/hamster/sorted_set/map_spec.rb +0 -36
- data/spec/lib/hamster/sorted_set/marshal_spec.rb +0 -37
- data/spec/lib/hamster/sorted_set/maximum_spec.rb +0 -37
- data/spec/lib/hamster/sorted_set/minimum_spec.rb +0 -20
- data/spec/lib/hamster/sorted_set/new_spec.rb +0 -52
- data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +0 -29
- data/spec/lib/hamster/sorted_set/sample_spec.rb +0 -14
- data/spec/lib/hamster/sorted_set/select_spec.rb +0 -62
- data/spec/lib/hamster/sorted_set/size_spec.rb +0 -18
- data/spec/lib/hamster/sorted_set/slice_spec.rb +0 -257
- data/spec/lib/hamster/sorted_set/sorting_spec.rb +0 -45
- data/spec/lib/hamster/sorted_set/subset_spec.rb +0 -48
- data/spec/lib/hamster/sorted_set/superset_spec.rb +0 -48
- data/spec/lib/hamster/sorted_set/take_spec.rb +0 -55
- data/spec/lib/hamster/sorted_set/take_while_spec.rb +0 -34
- data/spec/lib/hamster/sorted_set/to_set_spec.rb +0 -19
- data/spec/lib/hamster/sorted_set/union_spec.rb +0 -28
- data/spec/lib/hamster/sorted_set/up_to_spec.rb +0 -52
- data/spec/lib/hamster/sorted_set/values_at_spec.rb +0 -34
- data/spec/lib/hamster/vector/add_spec.rb +0 -68
- data/spec/lib/hamster/vector/assoc_spec.rb +0 -36
- data/spec/lib/hamster/vector/bsearch_spec.rb +0 -58
- data/spec/lib/hamster/vector/clear_spec.rb +0 -34
- data/spec/lib/hamster/vector/combination_spec.rb +0 -82
- data/spec/lib/hamster/vector/compact_spec.rb +0 -30
- data/spec/lib/hamster/vector/compare_spec.rb +0 -32
- data/spec/lib/hamster/vector/concat_spec.rb +0 -35
- data/spec/lib/hamster/vector/count_spec.rb +0 -18
- data/spec/lib/hamster/vector/delete_at_spec.rb +0 -54
- data/spec/lib/hamster/vector/delete_spec.rb +0 -31
- data/spec/lib/hamster/vector/drop_spec.rb +0 -42
- data/spec/lib/hamster/vector/drop_while_spec.rb +0 -55
- data/spec/lib/hamster/vector/each_index_spec.rb +0 -41
- data/spec/lib/hamster/vector/each_spec.rb +0 -45
- data/spec/lib/hamster/vector/each_with_index_spec.rb +0 -40
- data/spec/lib/hamster/vector/empty_spec.rb +0 -42
- data/spec/lib/hamster/vector/eql_spec.rb +0 -77
- data/spec/lib/hamster/vector/fetch_spec.rb +0 -65
- data/spec/lib/hamster/vector/fill_spec.rb +0 -89
- data/spec/lib/hamster/vector/first_spec.rb +0 -19
- data/spec/lib/hamster/vector/flat_map_spec.rb +0 -51
- data/spec/lib/hamster/vector/flatten_spec.rb +0 -44
- data/spec/lib/hamster/vector/get_spec.rb +0 -75
- data/spec/lib/hamster/vector/group_by_spec.rb +0 -58
- data/spec/lib/hamster/vector/insert_spec.rb +0 -69
- data/spec/lib/hamster/vector/inspect_spec.rb +0 -50
- data/spec/lib/hamster/vector/map_spec.rb +0 -52
- data/spec/lib/hamster/vector/marshal_spec.rb +0 -32
- data/spec/lib/hamster/vector/maximum_spec.rb +0 -34
- data/spec/lib/hamster/vector/minimum_spec.rb +0 -34
- data/spec/lib/hamster/vector/multiply_spec.rb +0 -48
- data/spec/lib/hamster/vector/new_spec.rb +0 -51
- data/spec/lib/hamster/vector/partition_spec.rb +0 -53
- data/spec/lib/hamster/vector/permutation_spec.rb +0 -92
- data/spec/lib/hamster/vector/pop_spec.rb +0 -27
- data/spec/lib/hamster/vector/product_spec.rb +0 -71
- data/spec/lib/hamster/vector/reject_spec.rb +0 -44
- data/spec/lib/hamster/vector/repeated_combination_spec.rb +0 -78
- data/spec/lib/hamster/vector/repeated_permutation_spec.rb +0 -94
- data/spec/lib/hamster/vector/reverse_each_spec.rb +0 -32
- data/spec/lib/hamster/vector/reverse_spec.rb +0 -22
- data/spec/lib/hamster/vector/rindex_spec.rb +0 -37
- data/spec/lib/hamster/vector/rotate_spec.rb +0 -74
- data/spec/lib/hamster/vector/sample_spec.rb +0 -14
- data/spec/lib/hamster/vector/select_spec.rb +0 -64
- data/spec/lib/hamster/vector/set_spec.rb +0 -175
- data/spec/lib/hamster/vector/shift_spec.rb +0 -28
- data/spec/lib/hamster/vector/shuffle_spec.rb +0 -44
- data/spec/lib/hamster/vector/slice_spec.rb +0 -241
- data/spec/lib/hamster/vector/sorting_spec.rb +0 -57
- data/spec/lib/hamster/vector/take_spec.rb +0 -43
- data/spec/lib/hamster/vector/take_while_spec.rb +0 -35
- data/spec/lib/hamster/vector/to_set_spec.rb +0 -23
- data/spec/lib/hamster/vector/transpose_spec.rb +0 -49
- data/spec/lib/hamster/vector/uniq_spec.rb +0 -56
- data/spec/lib/hamster/vector/unshift_spec.rb +0 -29
- data/spec/lib/hamster/vector/update_in_spec.rb +0 -83
- data/spec/lib/hamster/vector/values_at_spec.rb +0 -34
- data/spec/lib/hamster/vector/zip_spec.rb +0 -58
data/lib/hamster/hash.rb
CHANGED
@@ -1,823 +1,205 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
1
3
|
require "hamster/immutable"
|
2
4
|
require "hamster/undefined"
|
3
|
-
require "hamster/enumerable"
|
4
5
|
require "hamster/trie"
|
5
|
-
require "hamster/
|
6
|
-
require "hamster/vector"
|
6
|
+
require "hamster/list"
|
7
7
|
|
8
8
|
module Hamster
|
9
|
-
def self.hash(pairs =
|
10
|
-
|
9
|
+
def self.hash(pairs = {}, &block)
|
10
|
+
Hash.new(pairs, &block)
|
11
11
|
end
|
12
12
|
|
13
|
-
# A `Hamster::Hash` maps from a set of unique keys to corresponding values,
|
14
|
-
# much like a dictionary maps from words to definitions. Given a key, it can
|
15
|
-
# efficiently store and retrieve values. Looking up a key given its value is also
|
16
|
-
# possible, but less efficient. If an existing key is stored again, the new value
|
17
|
-
# will replace that which was previously stored.
|
18
|
-
#
|
19
|
-
# It behaves much like Ruby's built-in Hash, which we will call RubyHash
|
20
|
-
# for clarity. Like RubyHash, `Hamster::Hash` uses `#hash` and `#eql?` to define
|
21
|
-
# equality between keys. Keys with the same `#hash` code, but which are not `#eql?`
|
22
|
-
# to each other, can coexist in the same `Hamster::Hash`. To retrieve a previously
|
23
|
-
# stored value, the key provided must have the same `#hash` code and be `#eql?`
|
24
|
-
# to the one used for storage.
|
25
|
-
#
|
26
|
-
# A `Hamster::Hash` can be created in several ways:
|
27
|
-
#
|
28
|
-
# Hamster.hash('Jane Doe' => 10, 'Jim Doe' => 6)
|
29
|
-
# Hamster::Hash.new(font_size: 10, font_family: 'Arial')
|
30
|
-
# Hamster::Hash[first_name: 'John', last_name: 'Smith']
|
31
|
-
#
|
32
|
-
# If you want to write your own class which inherits from `Hamster::Hash`, you can
|
33
|
-
# use either of the latter 2 forms of initialization.
|
34
|
-
#
|
35
|
-
# Note that any `Enumerable` object which yields 2-element `[key, value]` arrays
|
36
|
-
# can be used to initialize a `Hamster::Hash`. So this is also possible:
|
37
|
-
#
|
38
|
-
# Hamster::Hash.new([[:first_name, 'John'], [:last_name, 'Smith']])
|
39
|
-
#
|
40
|
-
# Like RubyHash, key/value pairs can be added using {#store}. Unlike RubyHash,
|
41
|
-
# a new hash is returned, and the existing one is left unchanged:
|
42
|
-
#
|
43
|
-
# hash = Hamster::Hash[a: 100, b: 200]
|
44
|
-
# hash.store(:c, 500) # => Hamster::Hash[:a => 100, :b => 200, :c => 500]
|
45
|
-
# hash # => Hamster::Hash[:a => 100, :b => 200]
|
46
|
-
#
|
47
|
-
# You also use {#put}. The difference is that {#put} can optionally take a block which
|
48
|
-
# is used to calculate the value to be stored:
|
49
|
-
#
|
50
|
-
# hash.put(:a) { hash[:b] + 100 } # => Hamster::Hash[:a => 300, :b => 200]
|
51
|
-
#
|
52
|
-
# Since it is immutable, all methods which you might expect to "modify" a `Hamster::Hash`
|
53
|
-
# actually return a new hash and leave the existing one unchanged. This means that the
|
54
|
-
# `hash[key] = value` syntax used with RubyHashes *cannot* be used with `Hamster::Hash`.
|
55
|
-
#
|
56
|
-
# While a `Hamster::Hash` can iterate over its keys (or values), it does not
|
57
|
-
# guarantee any specific iteration order (unlike RubyHash). Likewise, methods like
|
58
|
-
# {#flatten} do not guarantee which order the returned key/value pairs will appear
|
59
|
-
# in.
|
60
|
-
#
|
61
|
-
# Like RubyHash, a `Hamster::Hash` can have a default block which is used when
|
62
|
-
# looking up a key which does not exist in the hash. Unlike RubyHash, the default
|
63
|
-
# block will only be passed the missing key, not the hash itself:
|
64
|
-
#
|
65
|
-
# hash = Hamster::Hash.new { |n| n * 10 }
|
66
|
-
# hash[5] # => 50
|
67
|
-
#
|
68
|
-
# A default block can only be set when creating a `Hamster::Hash` with `Hamster::Hash.new` or
|
69
|
-
# {Hamster.hash Hamster.hash}, not with {Hamster::Hash.[] Hamster::Hash[]}. Default blocks
|
70
|
-
# do not survive marshalling and unmarshalling.
|
71
|
-
#
|
72
13
|
class Hash
|
14
|
+
extend Forwardable
|
73
15
|
include Immutable
|
74
|
-
include Enumerable
|
75
16
|
|
76
17
|
class << self
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
# Hamster::Hash["A" => 1, "B" => 2]
|
81
|
-
# # => Hamster::Hash["A" => 1, "B" => 2]
|
82
|
-
# Hamster::Hash[["A", 1], ["B", 2]]
|
83
|
-
# # => Hamster::Hash["A" => 1, "B" => 2]
|
84
|
-
#
|
85
|
-
# @return [Hash]
|
86
|
-
def [](pairs = nil)
|
87
|
-
(pairs.nil? || pairs.empty?) ? empty : new(pairs)
|
88
|
-
end
|
89
|
-
|
90
|
-
# Return an empty `Hash`. If used on a subclass, returns an empty instance
|
91
|
-
# of that class.
|
92
|
-
#
|
93
|
-
# @return [Hash]
|
94
|
-
def empty
|
95
|
-
@empty ||= self.new
|
18
|
+
def new(pairs = {}, &block)
|
19
|
+
@empty ||= super()
|
20
|
+
pairs.reduce(block_given? ? super(&block) : @empty) { |hash, pair| hash.put(pair.first, pair.last) }
|
96
21
|
end
|
97
22
|
|
98
|
-
|
99
|
-
# instance quickly after obtaining a modified {Trie}.
|
100
|
-
#
|
101
|
-
# @return [Hash]
|
102
|
-
# @private
|
103
|
-
def alloc(trie = EmptyTrie, block = nil)
|
104
|
-
obj = allocate
|
105
|
-
obj.instance_variable_set(:@trie, trie)
|
106
|
-
obj.instance_variable_set(:@default, block)
|
107
|
-
obj
|
108
|
-
end
|
23
|
+
attr_reader :empty
|
109
24
|
end
|
110
25
|
|
111
|
-
def initialize(
|
112
|
-
@trie =
|
26
|
+
def initialize(&block)
|
27
|
+
@trie = EmptyTrie
|
113
28
|
@default = block
|
114
29
|
end
|
115
30
|
|
116
|
-
# Return the default block if there is one. Otherwise, return `nil`.
|
117
|
-
#
|
118
|
-
# @return [Proc]
|
119
|
-
def default_proc
|
120
|
-
@default
|
121
|
-
end
|
122
|
-
|
123
|
-
# Return the number of key/value pairs in this `Hash`.
|
124
|
-
#
|
125
|
-
# @example
|
126
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].size # => 3
|
127
|
-
#
|
128
|
-
# @return [Integer]
|
129
31
|
def size
|
130
32
|
@trie.size
|
131
33
|
end
|
132
|
-
|
34
|
+
def_delegator :self, :size, :length
|
133
35
|
|
134
|
-
# Return `true` if this `Hash` contains no key/value pairs.
|
135
|
-
#
|
136
|
-
# @return [Boolean]
|
137
36
|
def empty?
|
138
37
|
@trie.empty?
|
139
38
|
end
|
39
|
+
def_delegator :self, :empty?, :null?
|
140
40
|
|
141
|
-
# Return `true` if the given key object is present in this `Hash`. More precisely,
|
142
|
-
# return `true` if a key with the same `#hash` code, and which is also `#eql?`
|
143
|
-
# to the given key object is present.
|
144
|
-
#
|
145
|
-
# @example
|
146
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key?("B") # => true
|
147
|
-
#
|
148
|
-
# @param key [Object] The key to check for
|
149
|
-
# @return [Boolean]
|
150
41
|
def key?(key)
|
151
42
|
@trie.key?(key)
|
152
43
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# Return `true` if this `Hash` has one or more keys which map to the provided value.
|
158
|
-
#
|
159
|
-
# @example
|
160
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].value?(2) # => true
|
161
|
-
#
|
162
|
-
# @param value [Object] The value to check for
|
163
|
-
# @return [Boolean]
|
164
|
-
def value?(value)
|
165
|
-
each { |k,v| return true if value == v }
|
166
|
-
false
|
167
|
-
end
|
168
|
-
alias :has_value? :value?
|
169
|
-
|
170
|
-
# Retrieve the value corresponding to the provided key object. If not found, and
|
171
|
-
# this `Hash` has a default block, the default block is called to provide the
|
172
|
-
# value.
|
173
|
-
#
|
174
|
-
# @example
|
175
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
176
|
-
# h["B"] # => 2
|
177
|
-
# h.get("B") # => 2
|
178
|
-
# h.get("Elephant") # => nil
|
179
|
-
#
|
180
|
-
# # Hamster Hash with a default proc:
|
181
|
-
# h = Hamster::Hash.new("A" => 1, "B" => 2, "C" => 3) { |key| key.size }
|
182
|
-
# h.get("B") # => 2
|
183
|
-
# h.get("Elephant") # => 8
|
184
|
-
#
|
185
|
-
# @param key [Object] The key to look up
|
186
|
-
# @return [Object]
|
44
|
+
def_delegator :self, :key?, :has_key?
|
45
|
+
def_delegator :self, :key?, :include?
|
46
|
+
def_delegator :self, :key?, :member?
|
47
|
+
|
187
48
|
def get(key)
|
188
49
|
entry = @trie.get(key)
|
189
50
|
if entry
|
190
|
-
entry
|
51
|
+
entry.value
|
191
52
|
elsif @default
|
192
53
|
@default.call(key)
|
193
54
|
end
|
194
55
|
end
|
195
|
-
|
196
|
-
|
197
|
-
# Retrieve the value corresponding to the given key object, or use the provided
|
198
|
-
# default value or block, or otherwise raise a `KeyError`.
|
199
|
-
#
|
200
|
-
# @overload fetch(key)
|
201
|
-
# Retrieve the value corresponding to the given key, or raise a `KeyError`
|
202
|
-
# if it is not found.
|
203
|
-
# @param key [Object] The key to look up
|
204
|
-
# @overload fetch(key) { |key| ... }
|
205
|
-
# Retrieve the value corresponding to the given key, or call the optional
|
206
|
-
# code block (with the missing key) and get its return value.
|
207
|
-
# @yield [key] The key which was not found
|
208
|
-
# @yieldreturn [Object] Object to return since the key was not found
|
209
|
-
# @param key [Object] The key to look up
|
210
|
-
# @overload fetch(key, default)
|
211
|
-
# Retrieve the value corresponding to the given key, or else return
|
212
|
-
# the provided `default` value.
|
213
|
-
# @param key [Object] The key to look up
|
214
|
-
# @param default [Object] Object to return if the key is not found
|
215
|
-
#
|
216
|
-
# @example
|
217
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
218
|
-
# h.fetch("B") # => 2
|
219
|
-
# h.fetch("Elephant") # => KeyError: key not found: "Elephant"
|
220
|
-
#
|
221
|
-
# # with a default value:
|
222
|
-
# h.fetch("B", 99) # => 2
|
223
|
-
# h.fetch("Elephant", 99) # => 99
|
224
|
-
#
|
225
|
-
# # with a block:
|
226
|
-
# h.fetch("B") { |key| key.size } # => 2
|
227
|
-
# h.fetch("Elephant") { |key| key.size } # => 8
|
228
|
-
#
|
229
|
-
# @return [Object]
|
56
|
+
def_delegator :self, :get, :[]
|
57
|
+
|
230
58
|
def fetch(key, default = Undefined)
|
231
59
|
entry = @trie.get(key)
|
232
60
|
if entry
|
233
|
-
entry
|
234
|
-
elsif block_given?
|
235
|
-
yield(key)
|
61
|
+
entry.value
|
236
62
|
elsif default != Undefined
|
237
63
|
default
|
64
|
+
elsif block_given?
|
65
|
+
yield
|
238
66
|
else
|
239
67
|
raise KeyError, "key not found: #{key.inspect}"
|
240
68
|
end
|
241
69
|
end
|
242
70
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
#
|
247
|
-
# If the `value` argument is missing, but an optional code block is provided,
|
248
|
-
# it will be passed the existing value (or `nil` if there is none) and what it
|
249
|
-
# returns will replace the existing value. This is useful for "transforming"
|
250
|
-
# the value associated with a certain key.
|
251
|
-
#
|
252
|
-
# Avoid mutating objects which are used as keys. `String`s are an exception --
|
253
|
-
# unfrozen `String`s which are used as keys are internally duplicated and
|
254
|
-
# frozen.
|
255
|
-
#
|
256
|
-
# @example
|
257
|
-
# h = Hamster::Hash["A" => 1, "B" => 2]
|
258
|
-
# h.put("C", 3)
|
259
|
-
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
260
|
-
# h.put("B") { |value| value * 10 }
|
261
|
-
# # => Hamster::Hash["A" => 1, "B" => 20]
|
262
|
-
#
|
263
|
-
# @param key [Object] The key to store
|
264
|
-
# @param value [Object] The value to associate it with
|
265
|
-
# @yield [value] The previously stored value
|
266
|
-
# @yieldreturn [Object] The new value to store
|
267
|
-
# @return [Hash]
|
268
|
-
def put(key, value = yield(get(key)))
|
269
|
-
new_trie = @trie.put(key, value)
|
270
|
-
if new_trie.equal?(@trie)
|
271
|
-
self
|
272
|
-
else
|
273
|
-
self.class.alloc(new_trie, @default)
|
274
|
-
end
|
71
|
+
def put(key, value = Undefined)
|
72
|
+
return put(key, yield(get(key))) if value.equal?(Undefined)
|
73
|
+
transform { @trie = @trie.put(key, value) }
|
275
74
|
end
|
276
75
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
#
|
281
|
-
# The code block receives the existing value of the deeply nested key (or
|
282
|
-
# `nil` if it doesn't exist). This is useful for "transforming" the value
|
283
|
-
# associated with a certain key.
|
284
|
-
#
|
285
|
-
# Note that the original `Hash` and sub-`Hash`es and sub-`Vector`s are left
|
286
|
-
# unmodified; new data structure copies are created along the path wherever
|
287
|
-
# needed.
|
288
|
-
#
|
289
|
-
# @example
|
290
|
-
# hash = Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 42]]]
|
291
|
-
# hash.update_in("a", "b", "c") { |value| value + 5 }
|
292
|
-
# # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
|
293
|
-
#
|
294
|
-
# @param key_path [Object(s)] List of keys which form the path to the key to be modified
|
295
|
-
# @yield [value] The previously stored value
|
296
|
-
# @yieldreturn [Object] The new value to store
|
297
|
-
# @return [Hash]
|
298
|
-
def update_in(*key_path, &block)
|
299
|
-
if key_path.empty?
|
300
|
-
raise ArgumentError, "must have at least one key in path"
|
301
|
-
end
|
302
|
-
key = key_path[0]
|
303
|
-
if key_path.size == 1
|
304
|
-
new_value = block.call(get(key))
|
305
|
-
else
|
306
|
-
value = fetch(key, EmptyHash)
|
307
|
-
new_value = value.update_in(*key_path[1..-1], &block)
|
308
|
-
end
|
309
|
-
put(key, new_value)
|
76
|
+
def delete(key)
|
77
|
+
trie = @trie.delete(key)
|
78
|
+
transform_unless(trie.equal?(@trie)) { @trie = trie }
|
310
79
|
end
|
311
80
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
#
|
316
|
-
# Avoid mutating objects which are used as keys. `String`s are an exception --
|
317
|
-
# unfrozen `String`s which are used as keys are internally duplicated and
|
318
|
-
# frozen.
|
319
|
-
#
|
320
|
-
# @example
|
321
|
-
# Hamster::Hash["A" => 1, "B" => 2].store("C", 3)
|
322
|
-
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
323
|
-
#
|
324
|
-
# @param key [Object] The key to store
|
325
|
-
# @param value [Object] The value to associate it with
|
326
|
-
# @return [Hash]
|
327
|
-
def store(key, value)
|
328
|
-
put(key, value)
|
81
|
+
def each
|
82
|
+
return self unless block_given?
|
83
|
+
@trie.each { |entry| yield(entry.key, entry.value) }
|
329
84
|
end
|
85
|
+
def_delegator :self, :each, :foreach
|
330
86
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].delete("B")
|
336
|
-
# # => Hamster::Hash["A" => 1, "C" => 3]
|
337
|
-
#
|
338
|
-
# @param key [Object] The key to remove
|
339
|
-
# @return [Hash]
|
340
|
-
def delete(key)
|
341
|
-
derive_new_hash(@trie.delete(key))
|
87
|
+
def map
|
88
|
+
return self unless block_given?
|
89
|
+
return self if empty?
|
90
|
+
transform { @trie = @trie.reduce(EmptyTrie) { |trie, entry| trie.put(*yield(entry.key, entry.value)) } }
|
342
91
|
end
|
92
|
+
def_delegator :self, :map, :collect
|
343
93
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
#
|
348
|
-
# @example
|
349
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each { |k, v| puts "k=#{k} v=#{v}" }
|
350
|
-
#
|
351
|
-
# k=A v=1
|
352
|
-
# k=B v=2
|
353
|
-
# k=C v=3
|
354
|
-
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
355
|
-
#
|
356
|
-
# @return [self]
|
357
|
-
def each(&block)
|
358
|
-
return to_enum if not block_given?
|
359
|
-
@trie.each(&block)
|
360
|
-
self
|
361
|
-
end
|
362
|
-
alias :each_pair :each
|
363
|
-
|
364
|
-
# Call the block once for each key/value pair in this `Hash`, passing the key/value
|
365
|
-
# pair as parameters. Iteration order will be the opposite of {#each}.
|
366
|
-
#
|
367
|
-
# @example
|
368
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].reverse_each { |k, v| puts "k=#{k} v=#{v}" }
|
369
|
-
#
|
370
|
-
# k=C v=3
|
371
|
-
# k=B v=2
|
372
|
-
# k=A v=1
|
373
|
-
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
374
|
-
#
|
375
|
-
# @return [self]
|
376
|
-
def reverse_each(&block)
|
377
|
-
return enum_for(:reverse_each) if not block_given?
|
378
|
-
@trie.reverse_each(&block)
|
379
|
-
self
|
94
|
+
def reduce(memoization)
|
95
|
+
return memoization unless block_given?
|
96
|
+
@trie.reduce(memoization) { |memo, entry| yield(memo, entry.key, entry.value) }
|
380
97
|
end
|
98
|
+
def_delegator :self, :reduce, :inject
|
99
|
+
def_delegator :self, :reduce, :fold
|
100
|
+
def_delegator :self, :reduce, :foldr
|
381
101
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
#
|
388
|
-
# k=A
|
389
|
-
# k=B
|
390
|
-
# k=C
|
391
|
-
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
392
|
-
#
|
393
|
-
# @return [self]
|
394
|
-
def each_key
|
395
|
-
return enum_for(:each_key) if not block_given?
|
396
|
-
@trie.each { |k,v| yield k }
|
397
|
-
self
|
102
|
+
def filter
|
103
|
+
return self unless block_given?
|
104
|
+
trie = @trie.filter { |entry| yield(entry.key, entry.value) }
|
105
|
+
return self.class.empty if trie.empty?
|
106
|
+
transform_unless(trie.equal?(@trie)) { @trie = trie }
|
398
107
|
end
|
108
|
+
def_delegator :self, :filter, :select
|
109
|
+
def_delegator :self, :filter, :find_all
|
399
110
|
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
# @example
|
404
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_value { |v| puts "v=#{v}" }
|
405
|
-
#
|
406
|
-
# v=1
|
407
|
-
# v=2
|
408
|
-
# v=3
|
409
|
-
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
410
|
-
#
|
411
|
-
# @return [self]
|
412
|
-
def each_value
|
413
|
-
return enum_for(:each_value) if not block_given?
|
414
|
-
@trie.each { |k,v| yield v }
|
415
|
-
self
|
111
|
+
def remove
|
112
|
+
return self unless block_given?
|
113
|
+
filter { |key, value| !yield(key, value) }
|
416
114
|
end
|
115
|
+
def_delegator :self, :remove, :reject
|
116
|
+
def_delegator :self, :remove, :delete_if
|
417
117
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
# @example
|
423
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
424
|
-
# h.map { |k, v| ["new-#{k}", v * v] }
|
425
|
-
# # => Hash["new-C" => 9, "new-B" => 4, "new-A" => 1]
|
426
|
-
#
|
427
|
-
# @return [Hash]
|
428
|
-
def map
|
429
|
-
return enum_for(:map) unless block_given?
|
430
|
-
return self if empty?
|
431
|
-
self.class.new(super, &@default)
|
432
|
-
end
|
433
|
-
alias :collect :map
|
434
|
-
|
435
|
-
# Return a new `Hash` with all the key/value pairs for which the block returns true.
|
436
|
-
#
|
437
|
-
# @example
|
438
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
439
|
-
# h.select { |k, v| v >= 2 }
|
440
|
-
# # => Hamster::Hash["B" => 2, "C" => 3]
|
441
|
-
#
|
442
|
-
# @return [Hash]
|
443
|
-
def select(&block)
|
444
|
-
return enum_for(:select) unless block_given?
|
445
|
-
derive_new_hash(@trie.select(&block))
|
118
|
+
def any?
|
119
|
+
return !empty? unless block_given?
|
120
|
+
each { |key, value| return true if yield(key, value) }
|
121
|
+
false
|
446
122
|
end
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
# @example
|
454
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
455
|
-
# h.find { |k, v| v.even? }
|
456
|
-
# # => ["B", 2]
|
457
|
-
#
|
458
|
-
# @return [Array]
|
459
|
-
def find
|
460
|
-
return enum_for(:find) unless block_given?
|
461
|
-
each { |entry| return entry if yield entry }
|
462
|
-
nil
|
123
|
+
def_delegator :self, :any?, :exist?
|
124
|
+
def_delegator :self, :any?, :exists?
|
125
|
+
|
126
|
+
def all?
|
127
|
+
each { |key, value| return false unless yield(key, value) } if block_given?
|
128
|
+
true
|
463
129
|
end
|
464
|
-
|
465
|
-
|
466
|
-
# Return a new `Hash` containing all the key/value pairs from this `Hash` and
|
467
|
-
# `other`. If no block is provided, the value for entries with colliding keys
|
468
|
-
# will be that from `other`. Otherwie, the value for each duplicate key is
|
469
|
-
# determined by called the block with the key, its value in this `Hash`, and
|
470
|
-
# its value in `other`.
|
471
|
-
#
|
472
|
-
# `other` can be a `Hamster::Hash`, a built-in Ruby `Hash`, or any `Enumerable`
|
473
|
-
# object which yields `[key, value]` pairs.
|
474
|
-
#
|
475
|
-
# @example
|
476
|
-
# h1 = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
477
|
-
# h2 = Hamster::Hash["C" => 70, "D" => 80]
|
478
|
-
# h1.merge(h2)
|
479
|
-
# # => Hamster::Hash["C" => 70, "A" => 1, "D" => 80, "B" => 2]
|
480
|
-
# h1.merge(h2) { |key, v1, v2| v1 + v2 }
|
481
|
-
# # => Hamster::Hash["C" => 73, "A" => 1, "D" => 80, "B" => 2]
|
482
|
-
#
|
483
|
-
# @param other [Enumerable] The collection to merge with
|
484
|
-
# @yieldparam key [Object] The key which was present in both collections
|
485
|
-
# @yieldparam my_value [Object] The associated value from this `Hash`
|
486
|
-
# @yieldparam other_value [Object] The associated value from the other collection
|
487
|
-
# @yieldreturn [Object] The value to associate this key with in the new `Hash`
|
488
|
-
# @return [Hash]
|
489
|
-
def merge(other)
|
490
|
-
trie = if block_given?
|
491
|
-
other.reduce(@trie) do |trie, (key, value)|
|
492
|
-
if entry = trie.get(key)
|
493
|
-
trie.put(key, yield(key, entry[1], value))
|
494
|
-
else
|
495
|
-
trie.put(key, value)
|
496
|
-
end
|
497
|
-
end
|
498
|
-
else
|
499
|
-
@trie.bulk_put(other)
|
500
|
-
end
|
130
|
+
def_delegator :self, :all?, :forall?
|
501
131
|
|
502
|
-
|
132
|
+
def none?
|
133
|
+
return empty? unless block_given?
|
134
|
+
each { |key, value| return false if yield(key, value) }
|
135
|
+
true
|
503
136
|
end
|
504
137
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
#
|
510
|
-
# @example
|
511
|
-
# h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
|
512
|
-
# h.sort { |(k1, v1), (k2, v2)| k1.size <=> k2.size }
|
513
|
-
# # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
|
514
|
-
#
|
515
|
-
# @return [Vector]
|
516
|
-
def sort
|
517
|
-
Vector.new(super)
|
138
|
+
def find
|
139
|
+
return nil unless block_given?
|
140
|
+
each { |key, value| return Tuple.new(key, value) if yield(key, value) }
|
141
|
+
nil
|
518
142
|
end
|
143
|
+
def_delegator :self, :find, :detect
|
519
144
|
|
520
|
-
|
521
|
-
|
522
|
-
# passing each pair to the code block to obtain a sort key object, and comparing
|
523
|
-
# the sort keys using `#<=>`.
|
524
|
-
# See `Enumerable#sort_by`.
|
525
|
-
#
|
526
|
-
# @example
|
527
|
-
# h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
|
528
|
-
# h.sort_by { |key, value| key.size }
|
529
|
-
# # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
|
530
|
-
#
|
531
|
-
# @return [Vector]
|
532
|
-
def sort_by
|
533
|
-
Vector.new(super)
|
145
|
+
def merge(other)
|
146
|
+
transform { @trie = other.reduce(@trie, &:put) }
|
534
147
|
end
|
148
|
+
def_delegator :self, :merge, :+
|
535
149
|
|
536
|
-
# Return a new `Hash` with the associations for all of the given `keys` removed.
|
537
|
-
#
|
538
|
-
# @example
|
539
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
540
|
-
# h.except("A", "C") # => Hamster::Hash["B" => 2]
|
541
|
-
#
|
542
|
-
# @param keys [Array] The keys to remove
|
543
|
-
# @return [Hash]
|
544
150
|
def except(*keys)
|
545
151
|
keys.reduce(self) { |hash, key| hash.delete(key) }
|
546
152
|
end
|
547
153
|
|
548
|
-
# Return a new `Hash` with only the associations for the `wanted` keys retained.
|
549
|
-
# If any of the `wanted` keys are not present in this `Hash`, they will not be present
|
550
|
-
# in the returned `Hash` either.
|
551
|
-
#
|
552
|
-
# @example
|
553
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
554
|
-
# h.slice("B", "C") # => Hamster::Hash["B" => 2, "C" => 3]
|
555
|
-
#
|
556
|
-
# @param wanted [Array] The keys to retain
|
557
|
-
# @return [Hash]
|
558
154
|
def slice(*wanted)
|
559
|
-
|
560
|
-
wanted.each { |key| trie.put!(key, get(key)) if key?(key) }
|
561
|
-
self.class.alloc(trie, @default)
|
562
|
-
end
|
563
|
-
|
564
|
-
# Return a {Vector} of the values which correspond to the `wanted` keys.
|
565
|
-
# If any of the `wanted` keys are not present in this `Hash`, they will be skipped.
|
566
|
-
#
|
567
|
-
# @example
|
568
|
-
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
569
|
-
# h.values_at("B", "A") # => Hamster::Vector[2, 1]
|
570
|
-
#
|
571
|
-
# @param wanted [Array] The keys to retrieve
|
572
|
-
# @return [Vector]
|
573
|
-
def values_at(*wanted)
|
574
|
-
array = []
|
575
|
-
wanted.each { |key| array << get(key) if key?(key) }
|
576
|
-
Vector.new(array.freeze)
|
155
|
+
except(*keys - wanted)
|
577
156
|
end
|
578
157
|
|
579
|
-
# Return a new {Set} populated with the keys from this `Hash`.
|
580
|
-
#
|
581
|
-
# @example
|
582
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].keys
|
583
|
-
# # => Hamster::Set["D", "C", "B", "A"]
|
584
|
-
#
|
585
|
-
# @return [Set]
|
586
158
|
def keys
|
587
|
-
|
159
|
+
reduce(Hamster.set) { |keys, key, value| keys.add(key) }
|
588
160
|
end
|
589
161
|
|
590
|
-
# Return a new {Vector} populated with the values from this `Hash`.
|
591
|
-
#
|
592
|
-
# @example
|
593
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].values
|
594
|
-
# # => Hamster::Vector[2, 3, 2, 1]
|
595
|
-
#
|
596
|
-
# @return [Vector]
|
597
162
|
def values
|
598
|
-
|
599
|
-
end
|
600
|
-
|
601
|
-
# Return a new `Hash` created by using our keys as values, and values as keys.
|
602
|
-
# If there are multiple values which are equivalent (as determined by `#hash` and
|
603
|
-
# `#eql?`), only one out of each group of equivalent values will be retained.
|
604
|
-
#
|
605
|
-
# @example
|
606
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].invert
|
607
|
-
# # => Hamster::Hash[1 => "A", 3 => "C", 2 => "B"]
|
608
|
-
#
|
609
|
-
# @return [Hash]
|
610
|
-
def invert
|
611
|
-
pairs = []
|
612
|
-
each { |k,v| pairs << [v, k] }
|
613
|
-
self.class.new(pairs, &@default)
|
614
|
-
end
|
615
|
-
|
616
|
-
# Return a new {Vector} which is a one-dimensional flattening of this `Hash`.
|
617
|
-
# If `level` is 1, all the `[key, value]` pairs in the hash will be concatenated
|
618
|
-
# into one {Vector}. If `level` is greater than 1, keys or values which are
|
619
|
-
# themselves `Array`s or {Vector}s will be recursively flattened into the output
|
620
|
-
# {Vector}. The depth to which that flattening will be recursively applied is
|
621
|
-
# determined by `level`.
|
622
|
-
#
|
623
|
-
# As a special case, if `level` is 0, each `[key, value]` pair will be a
|
624
|
-
# separate element in the returned {Vector}.
|
625
|
-
#
|
626
|
-
# @example
|
627
|
-
# h = Hamster::Hash["A" => 1, "B" => [2, 3, 4]]
|
628
|
-
# h.flatten
|
629
|
-
# # => Hamster::Vector["A", 1, "B", [2, 3, 4]]
|
630
|
-
# h.flatten(2)
|
631
|
-
# # => Hamster::Vector["A", 1, "B", 2, 3, 4]
|
632
|
-
#
|
633
|
-
# @param level [Integer] The number of times to recursively flatten the `[key, value]` pairs in this `Hash`.
|
634
|
-
# @return [Vector]
|
635
|
-
def flatten(level = 1)
|
636
|
-
return Vector.new(self) if level == 0
|
637
|
-
array = []
|
638
|
-
each { |k,v| array << k; array << v }
|
639
|
-
array.flatten!(level-1) if level > 1
|
640
|
-
Vector.new(array.freeze)
|
641
|
-
end
|
642
|
-
|
643
|
-
# Searches through the `Hash`, comparing `obj` with each key (using `#==`).
|
644
|
-
# When a matching key is found, return the `[key, value]` pair as an array.
|
645
|
-
# Return `nil` if no match is found.
|
646
|
-
#
|
647
|
-
# @example
|
648
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].assoc("B") # => ["B", 2]
|
649
|
-
#
|
650
|
-
# @param obj [Object] The key to search for (using #==)
|
651
|
-
# @return [Array]
|
652
|
-
def assoc(obj)
|
653
|
-
each { |entry| return entry if obj == entry[0] }
|
654
|
-
nil
|
655
|
-
end
|
656
|
-
|
657
|
-
# Searches through the `Hash`, comparing `obj` with each value (using `#==`).
|
658
|
-
# When a matching value is found, return the `[key, value]` pair as an array.
|
659
|
-
# Return `nil` if no match is found.
|
660
|
-
#
|
661
|
-
# @example
|
662
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].rassoc(2) # => ["B", 2]
|
663
|
-
#
|
664
|
-
# @param obj [Object] The value to search for (using #==)
|
665
|
-
# @return [Array]
|
666
|
-
def rassoc(obj)
|
667
|
-
each { |entry| return entry if obj == entry[1] }
|
668
|
-
nil
|
669
|
-
end
|
670
|
-
|
671
|
-
# Searches through the `Hash`, comparing `value` with each value (using `#==`).
|
672
|
-
# When a matching value is found, return its associated key object.
|
673
|
-
# Return `nil` if no match is found.
|
674
|
-
#
|
675
|
-
# @example
|
676
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key(2) # => "B"
|
677
|
-
#
|
678
|
-
# @param value [Object] The value to search for (using #==)
|
679
|
-
# @return [Object]
|
680
|
-
def key(value)
|
681
|
-
each { |entry| return entry[0] if value == entry[1] }
|
682
|
-
nil
|
683
|
-
end
|
684
|
-
|
685
|
-
# Return a randomly chosen `[key, value]` pair from this `Hash`. If the hash is empty,
|
686
|
-
# return `nil`.
|
687
|
-
#
|
688
|
-
# @example
|
689
|
-
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].sample
|
690
|
-
# # => ["C", 3]
|
691
|
-
#
|
692
|
-
# @return [Array]
|
693
|
-
def sample
|
694
|
-
@trie.at(rand(size))
|
163
|
+
reduce(Hamster.list) { |values, key, value| values.cons(value) }
|
695
164
|
end
|
696
165
|
|
697
|
-
# Return an empty `Hash` instance, of the same class as this one. Useful if you
|
698
|
-
# have multiple subclasses of `Hash` and want to treat them polymorphically.
|
699
|
-
# Maintains the default block, if there is one.
|
700
|
-
#
|
701
|
-
# @return [Hash]
|
702
166
|
def clear
|
703
|
-
|
704
|
-
self.class.alloc(EmptyTrie, @default)
|
705
|
-
else
|
706
|
-
self.class.empty
|
707
|
-
end
|
167
|
+
self.class.empty
|
708
168
|
end
|
709
169
|
|
710
|
-
# Return true if `other` has the same type and contents as this `Hash`.
|
711
|
-
#
|
712
|
-
# @param other [Object] The collection to compare with
|
713
|
-
# @return [Boolean]
|
714
170
|
def eql?(other)
|
715
|
-
return true if other.equal?(self)
|
716
171
|
instance_of?(other.class) && @trie.eql?(other.instance_variable_get(:@trie))
|
717
172
|
end
|
173
|
+
def_delegator :self, :eql?, :==
|
718
174
|
|
719
|
-
# Return true if `other` has the same contents as this `Hash`. Will convert
|
720
|
-
# `other` to a Ruby `Hash` using `#to_hash` if necessary.
|
721
|
-
#
|
722
|
-
# @param other [Object] The object to compare with
|
723
|
-
# @return [Boolean]
|
724
|
-
def ==(other)
|
725
|
-
self.eql?(other) || (other.respond_to?(:to_hash) && to_hash.eql?(other.to_hash))
|
726
|
-
end
|
727
|
-
|
728
|
-
# See `Object#hash`.
|
729
|
-
# @return [Integer]
|
730
175
|
def hash
|
731
|
-
keys.
|
176
|
+
keys.sort.reduce(0) do |hash, key|
|
732
177
|
(hash << 32) - hash + key.hash + get(key).hash
|
733
178
|
end
|
734
179
|
end
|
735
180
|
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
# block (if there is one) will be lost when doing this.
|
740
|
-
#
|
741
|
-
# @return [String]
|
742
|
-
def inspect
|
743
|
-
result = "#{self.class}["
|
744
|
-
i = 0
|
745
|
-
each do |key, val|
|
746
|
-
result << ', ' if i > 0
|
747
|
-
result << key.inspect << ' => ' << val.inspect
|
748
|
-
i += 1
|
749
|
-
end
|
750
|
-
result << "]"
|
751
|
-
end
|
181
|
+
def_delegator :self, :dup, :uniq
|
182
|
+
def_delegator :self, :dup, :nub
|
183
|
+
def_delegator :self, :dup, :remove_duplicates
|
752
184
|
|
753
|
-
|
754
|
-
|
755
|
-
# the screen into account, and which indents nested structures to make them easier
|
756
|
-
# to read.
|
757
|
-
#
|
758
|
-
# @private
|
759
|
-
def pretty_print(pp)
|
760
|
-
pp.group(1, "#{self.class}[", "]") do
|
761
|
-
pp.breakable ''
|
762
|
-
pp.seplist(self, nil) do |key, val|
|
763
|
-
pp.group do
|
764
|
-
key.pretty_print(pp)
|
765
|
-
pp.text ' => '
|
766
|
-
pp.group(1) do
|
767
|
-
pp.breakable ''
|
768
|
-
val.pretty_print(pp)
|
769
|
-
end
|
770
|
-
end
|
771
|
-
end
|
772
|
-
end
|
185
|
+
def inspect
|
186
|
+
"{#{reduce([]) { |memo, key, value| memo << "#{key.inspect} => #{value.inspect}" }.join(", ")}}"
|
773
187
|
end
|
774
188
|
|
775
|
-
|
776
|
-
#
|
777
|
-
# @return [::Hash]
|
778
|
-
def to_hash
|
189
|
+
def marshal_dump
|
779
190
|
output = {}
|
780
191
|
each do |key, value|
|
781
192
|
output[key] = value
|
782
193
|
end
|
783
194
|
output
|
784
195
|
end
|
785
|
-
alias :to_h :to_hash
|
786
|
-
|
787
|
-
# @return [::Hash]
|
788
|
-
# @private
|
789
|
-
def marshal_dump
|
790
|
-
to_hash
|
791
|
-
end
|
792
196
|
|
793
|
-
# @private
|
794
197
|
def marshal_load(dictionary)
|
795
|
-
@trie =
|
796
|
-
|
797
|
-
|
798
|
-
private
|
799
|
-
|
800
|
-
# Return a new `Hash` which is derived from this one, using a modified {Trie}.
|
801
|
-
# The new `Hash` will retain the existing default block, if there is one.
|
802
|
-
#
|
803
|
-
def derive_new_hash(trie)
|
804
|
-
if trie.equal?(@trie)
|
805
|
-
self
|
806
|
-
elsif trie.empty?
|
807
|
-
if @default
|
808
|
-
self.class.alloc(EmptyTrie, @default)
|
809
|
-
else
|
810
|
-
self.class.empty
|
811
|
-
end
|
812
|
-
else
|
813
|
-
self.class.alloc(trie, @default)
|
198
|
+
@trie = dictionary.reduce EmptyTrie do |trie, key_value|
|
199
|
+
trie.put(key_value.first, key_value.last)
|
814
200
|
end
|
815
201
|
end
|
816
202
|
end
|
817
203
|
|
818
|
-
|
819
|
-
# invoked with no arguments; also returned by `Hash.empty`. Prefer using this
|
820
|
-
# one rather than creating many empty hashes using `Hash.new`.
|
821
|
-
#
|
822
|
-
EmptyHash = Hamster::Hash.empty
|
204
|
+
EmptyHash = Hamster::Hash.new
|
823
205
|
end
|