hamster 1.0.1.pre.rc3 → 2.0.0
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 -0
- data/lib/hamster/associable.rb +49 -0
- data/lib/hamster/core_ext/enumerable.rb +3 -13
- data/lib/hamster/core_ext/io.rb +1 -1
- data/lib/hamster/core_ext/struct.rb +9 -0
- data/lib/hamster/deque.rb +57 -38
- data/lib/hamster/enumerable.rb +14 -41
- data/lib/hamster/experimental/mutable_queue.rb +5 -8
- data/lib/hamster/experimental/mutable_set.rb +6 -7
- data/lib/hamster/hash.rb +301 -110
- data/lib/hamster/immutable.rb +1 -1
- data/lib/hamster/list.rb +479 -194
- data/lib/hamster/mutable_hash.rb +6 -7
- data/lib/hamster/nested.rb +78 -0
- data/lib/hamster/read_copy_update.rb +1 -1
- data/lib/hamster/set.rb +198 -88
- data/lib/hamster/sorted_set.rb +706 -261
- data/lib/hamster/trie.rb +134 -15
- data/lib/hamster/vector.rb +571 -140
- data/lib/hamster/version.rb +3 -1
- data/spec/lib/hamster/associable/associable_spec.rb +150 -0
- data/spec/lib/hamster/core_ext/array_spec.rb +1 -1
- data/spec/lib/hamster/core_ext/enumerable_spec.rb +2 -2
- data/spec/lib/hamster/core_ext/io_spec.rb +1 -1
- data/spec/lib/hamster/deque/clear_spec.rb +3 -3
- data/spec/lib/hamster/deque/construction_spec.rb +8 -8
- data/spec/lib/hamster/deque/copying_spec.rb +1 -1
- data/spec/lib/hamster/deque/dequeue_spec.rb +12 -4
- data/spec/lib/hamster/deque/empty_spec.rb +14 -16
- data/spec/lib/hamster/deque/enqueue_spec.rb +4 -4
- data/spec/lib/hamster/deque/first_spec.rb +18 -0
- data/spec/lib/hamster/deque/inspect_spec.rb +1 -1
- data/spec/lib/hamster/deque/last_spec.rb +9 -11
- data/spec/lib/hamster/deque/marshal_spec.rb +6 -6
- data/spec/lib/hamster/deque/new_spec.rb +5 -5
- data/spec/lib/hamster/deque/pop_spec.rb +15 -3
- data/spec/lib/hamster/deque/pretty_print_spec.rb +24 -0
- data/spec/lib/hamster/deque/push_spec.rb +37 -0
- data/spec/lib/hamster/deque/shift_spec.rb +30 -0
- data/spec/lib/hamster/deque/size_spec.rb +1 -1
- data/spec/lib/hamster/deque/to_a_spec.rb +2 -2
- data/spec/lib/hamster/deque/to_ary_spec.rb +1 -1
- data/spec/lib/hamster/deque/to_list_spec.rb +3 -3
- data/spec/lib/hamster/deque/unshift_spec.rb +8 -3
- data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +3 -3
- data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +3 -3
- data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +3 -3
- data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +3 -3
- data/spec/lib/hamster/hash/all_spec.rb +32 -34
- data/spec/lib/hamster/hash/any_spec.rb +34 -36
- data/spec/lib/hamster/hash/assoc_spec.rb +3 -3
- data/spec/lib/hamster/hash/clear_spec.rb +4 -4
- data/spec/lib/hamster/hash/construction_spec.rb +8 -8
- data/spec/lib/hamster/hash/copying_spec.rb +1 -1
- data/spec/lib/hamster/hash/default_proc_spec.rb +3 -3
- data/spec/lib/hamster/hash/delete_spec.rb +4 -4
- data/spec/lib/hamster/hash/each_spec.rb +3 -3
- data/spec/lib/hamster/hash/each_with_index_spec.rb +1 -1
- data/spec/lib/hamster/hash/empty_spec.rb +13 -15
- data/spec/lib/hamster/hash/eql_spec.rb +4 -4
- data/spec/lib/hamster/hash/except_spec.rb +7 -7
- data/spec/lib/hamster/hash/fetch_spec.rb +10 -10
- data/spec/lib/hamster/hash/find_spec.rb +2 -2
- data/spec/lib/hamster/hash/flat_map_spec.rb +4 -4
- data/spec/lib/hamster/hash/flatten_spec.rb +13 -13
- data/spec/lib/hamster/hash/get_spec.rb +7 -7
- data/spec/lib/hamster/hash/has_key_spec.rb +3 -3
- data/spec/lib/hamster/hash/has_value_spec.rb +4 -4
- data/spec/lib/hamster/hash/hash_spec.rb +5 -5
- data/spec/lib/hamster/hash/inspect_spec.rb +2 -2
- data/spec/lib/hamster/hash/invert_spec.rb +6 -6
- data/spec/lib/hamster/hash/key_spec.rb +2 -2
- data/spec/lib/hamster/hash/keys_spec.rb +2 -2
- data/spec/lib/hamster/hash/map_spec.rb +4 -4
- data/spec/lib/hamster/hash/marshal_spec.rb +2 -2
- data/spec/lib/hamster/hash/merge_spec.rb +62 -56
- data/spec/lib/hamster/hash/min_max_spec.rb +9 -13
- data/spec/lib/hamster/hash/new_spec.rb +6 -6
- data/spec/lib/hamster/hash/none_spec.rb +3 -3
- data/spec/lib/hamster/hash/partition_spec.rb +2 -2
- data/spec/lib/hamster/hash/put_spec.rb +29 -7
- data/spec/lib/hamster/hash/reduce_spec.rb +4 -4
- data/spec/lib/hamster/hash/{remove_spec.rb → reject_spec.rb} +7 -7
- data/spec/lib/hamster/hash/reverse_each_spec.rb +1 -1
- data/spec/lib/hamster/hash/{filter_spec.rb → select_spec.rb} +6 -6
- data/spec/lib/hamster/hash/size_spec.rb +3 -3
- data/spec/lib/hamster/hash/slice_spec.rb +4 -4
- data/spec/lib/hamster/hash/sort_spec.rb +2 -2
- data/spec/lib/hamster/hash/store_spec.rb +29 -7
- data/spec/lib/hamster/hash/take_spec.rb +2 -2
- data/spec/lib/hamster/hash/to_a_spec.rb +1 -1
- data/spec/lib/hamster/hash/to_hash_spec.rb +4 -4
- data/spec/lib/hamster/hash/values_at_spec.rb +3 -3
- data/spec/lib/hamster/hash/values_spec.rb +2 -2
- data/spec/lib/hamster/immutable/new_spec.rb +14 -0
- data/spec/lib/hamster/list/add_spec.rb +16 -10
- data/spec/lib/hamster/list/all_spec.rb +33 -35
- data/spec/lib/hamster/list/any_spec.rb +29 -31
- data/spec/lib/hamster/list/append_spec.rb +6 -6
- data/spec/lib/hamster/list/at_spec.rb +1 -1
- data/spec/lib/hamster/list/break_spec.rb +4 -4
- data/spec/lib/hamster/list/cadr_spec.rb +9 -9
- data/spec/lib/hamster/list/chunk_spec.rb +5 -5
- data/spec/lib/hamster/list/clear_spec.rb +3 -3
- data/spec/lib/hamster/list/combination_spec.rb +3 -3
- data/spec/lib/hamster/list/compact_spec.rb +3 -3
- data/spec/lib/hamster/list/compare_spec.rb +3 -3
- data/spec/lib/hamster/list/cons_spec.rb +15 -17
- data/spec/lib/hamster/list/construction_spec.rb +20 -27
- data/spec/lib/hamster/list/copying_spec.rb +1 -1
- data/spec/lib/hamster/list/count_spec.rb +1 -1
- data/spec/lib/hamster/list/cycle_spec.rb +4 -4
- data/spec/lib/hamster/list/delete_at_spec.rb +4 -4
- data/spec/lib/hamster/list/drop_spec.rb +3 -3
- data/spec/lib/hamster/list/drop_while_spec.rb +3 -3
- data/spec/lib/hamster/list/each_slice_spec.rb +5 -5
- data/spec/lib/hamster/list/each_spec.rb +26 -28
- data/spec/lib/hamster/list/each_with_index_spec.rb +1 -1
- data/spec/lib/hamster/list/empty_spec.rb +13 -15
- data/spec/lib/hamster/list/eql_spec.rb +21 -21
- data/spec/lib/hamster/list/fill_spec.rb +8 -8
- data/spec/lib/hamster/list/find_all_spec.rb +3 -3
- data/spec/lib/hamster/list/find_index_spec.rb +1 -1
- data/spec/lib/hamster/list/find_spec.rb +1 -1
- data/spec/lib/hamster/list/flat_map_spec.rb +2 -2
- data/spec/lib/hamster/list/flatten_spec.rb +5 -5
- data/spec/lib/hamster/list/grep_spec.rb +4 -4
- data/spec/lib/hamster/list/group_by_spec.rb +6 -6
- data/spec/lib/hamster/list/hash_spec.rb +2 -2
- data/spec/lib/hamster/list/head_spec.rb +1 -1
- data/spec/lib/hamster/list/include_spec.rb +2 -2
- data/spec/lib/hamster/list/index_spec.rb +38 -0
- data/spec/lib/hamster/list/indices_spec.rb +62 -0
- data/spec/lib/hamster/list/init_spec.rb +3 -3
- data/spec/lib/hamster/list/inits_spec.rb +3 -3
- data/spec/lib/hamster/list/insert_spec.rb +1 -1
- data/spec/lib/hamster/list/inspect_spec.rb +1 -1
- data/spec/lib/hamster/list/intersperse_spec.rb +3 -3
- data/spec/lib/hamster/list/join_spec.rb +5 -5
- data/spec/lib/hamster/list/last_spec.rb +1 -1
- data/spec/lib/hamster/list/ltlt_spec.rb +20 -0
- data/spec/lib/hamster/list/map_spec.rb +4 -4
- data/spec/lib/hamster/list/maximum_spec.rb +24 -26
- data/spec/lib/hamster/list/merge_by_spec.rb +10 -10
- data/spec/lib/hamster/list/merge_spec.rb +10 -10
- data/spec/lib/hamster/list/minimum_spec.rb +24 -26
- data/spec/lib/hamster/list/multithreading_spec.rb +6 -6
- data/spec/lib/hamster/list/none_spec.rb +5 -5
- data/spec/lib/hamster/list/one_spec.rb +5 -5
- data/spec/lib/hamster/list/partition_spec.rb +8 -8
- data/spec/lib/hamster/list/permutation_spec.rb +8 -8
- data/spec/lib/hamster/list/pop_spec.rb +3 -3
- data/spec/lib/hamster/list/product_spec.rb +1 -1
- data/spec/lib/hamster/list/reduce_spec.rb +5 -48
- data/spec/lib/hamster/list/{remove_spec.rb → reject_spec.rb} +4 -4
- data/spec/lib/hamster/list/reverse_spec.rb +3 -3
- data/spec/lib/hamster/list/rotate_spec.rb +7 -7
- data/spec/lib/hamster/list/sample_spec.rb +1 -1
- data/spec/lib/hamster/list/select_spec.rb +3 -3
- data/spec/lib/hamster/list/size_spec.rb +1 -1
- data/spec/lib/hamster/list/slice_spec.rb +123 -123
- data/spec/lib/hamster/list/sorting_spec.rb +5 -5
- data/spec/lib/hamster/list/span_spec.rb +5 -5
- data/spec/lib/hamster/list/split_at_spec.rb +4 -4
- data/spec/lib/hamster/list/subsequences_spec.rb +1 -1
- data/spec/lib/hamster/list/sum_spec.rb +1 -1
- data/spec/lib/hamster/list/tail_spec.rb +4 -4
- data/spec/lib/hamster/list/tails_spec.rb +3 -3
- data/spec/lib/hamster/list/take_spec.rb +3 -3
- data/spec/lib/hamster/list/take_while_spec.rb +4 -4
- data/spec/lib/hamster/list/to_a_spec.rb +2 -2
- data/spec/lib/hamster/list/to_ary_spec.rb +1 -1
- data/spec/lib/hamster/list/to_list_spec.rb +1 -1
- data/spec/lib/hamster/list/to_set_spec.rb +1 -1
- data/spec/lib/hamster/list/union_spec.rb +4 -4
- data/spec/lib/hamster/list/uniq_spec.rb +23 -19
- data/spec/lib/hamster/list/zip_spec.rb +5 -5
- data/spec/lib/hamster/nested/construction_spec.rb +103 -0
- data/spec/lib/hamster/set/add_spec.rb +13 -11
- data/spec/lib/hamster/set/all_spec.rb +32 -34
- data/spec/lib/hamster/set/any_spec.rb +32 -34
- data/spec/lib/hamster/set/clear_spec.rb +3 -3
- data/spec/lib/hamster/set/compact_spec.rb +3 -3
- data/spec/lib/hamster/set/construction_spec.rb +3 -3
- data/spec/lib/hamster/set/copying_spec.rb +1 -1
- data/spec/lib/hamster/set/count_spec.rb +1 -1
- data/spec/lib/hamster/set/delete_spec.rb +8 -8
- data/spec/lib/hamster/set/difference_spec.rb +8 -8
- data/spec/lib/hamster/set/disjoint_spec.rb +1 -1
- data/spec/lib/hamster/set/each_spec.rb +2 -2
- data/spec/lib/hamster/set/empty_spec.rb +15 -17
- data/spec/lib/hamster/set/eqeq_spec.rb +3 -3
- data/spec/lib/hamster/set/eql_spec.rb +3 -3
- data/spec/lib/hamster/set/exclusion_spec.rb +7 -7
- data/spec/lib/hamster/set/find_spec.rb +2 -2
- data/spec/lib/hamster/set/first_spec.rb +29 -0
- data/spec/lib/hamster/set/flatten_spec.rb +9 -9
- data/spec/lib/hamster/set/grep_spec.rb +1 -1
- data/spec/lib/hamster/set/group_by_spec.rb +12 -12
- data/spec/lib/hamster/set/hash_spec.rb +3 -3
- data/spec/lib/hamster/set/include_spec.rb +8 -8
- data/spec/lib/hamster/set/inspect_spec.rb +2 -2
- data/spec/lib/hamster/set/intersect_spec.rb +1 -1
- data/spec/lib/hamster/set/intersection_spec.rb +13 -13
- data/spec/lib/hamster/set/join_spec.rb +6 -6
- data/spec/lib/hamster/set/map_spec.rb +7 -7
- data/spec/lib/hamster/set/marshal_spec.rb +2 -2
- data/spec/lib/hamster/set/maximum_spec.rb +22 -24
- data/spec/lib/hamster/set/minimum_spec.rb +22 -24
- data/spec/lib/hamster/set/new_spec.rb +5 -5
- data/spec/lib/hamster/set/none_spec.rb +5 -5
- data/spec/lib/hamster/set/one_spec.rb +6 -6
- data/spec/lib/hamster/set/partition_spec.rb +5 -5
- data/spec/lib/hamster/set/product_spec.rb +2 -2
- data/spec/lib/hamster/set/reduce_spec.rb +5 -5
- data/spec/lib/hamster/set/{remove_spec.rb → reject_spec.rb} +6 -6
- data/spec/lib/hamster/set/reverse_each_spec.rb +1 -1
- data/spec/lib/hamster/set/sample_spec.rb +1 -1
- data/spec/lib/hamster/set/{filter_spec.rb → select_spec.rb} +11 -11
- data/spec/lib/hamster/set/size_spec.rb +1 -1
- data/spec/lib/hamster/set/sorting_spec.rb +16 -5
- data/spec/lib/hamster/set/subset_spec.rb +2 -2
- data/spec/lib/hamster/set/sum_spec.rb +2 -2
- data/spec/lib/hamster/set/superset_spec.rb +2 -2
- data/spec/lib/hamster/set/to_a_spec.rb +2 -2
- data/spec/lib/hamster/set/to_list_spec.rb +2 -2
- data/spec/lib/hamster/set/to_set_spec.rb +1 -1
- data/spec/lib/hamster/set/union_spec.rb +23 -14
- data/spec/lib/hamster/sorted_set/above_spec.rb +11 -11
- data/spec/lib/hamster/sorted_set/add_spec.rb +8 -8
- data/spec/lib/hamster/sorted_set/at_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/below_spec.rb +11 -11
- data/spec/lib/hamster/sorted_set/between_spec.rb +11 -11
- data/spec/lib/hamster/sorted_set/clear_spec.rb +11 -2
- data/spec/lib/hamster/sorted_set/copying_spec.rb +21 -0
- data/spec/lib/hamster/sorted_set/delete_at_spec.rb +4 -4
- data/spec/lib/hamster/sorted_set/delete_spec.rb +21 -12
- data/spec/lib/hamster/sorted_set/difference_spec.rb +2 -2
- data/spec/lib/hamster/sorted_set/disjoint_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/drop_spec.rb +30 -3
- data/spec/lib/hamster/sorted_set/drop_while_spec.rb +4 -4
- data/spec/lib/hamster/sorted_set/each_spec.rb +16 -18
- data/spec/lib/hamster/sorted_set/empty_spec.rb +12 -14
- data/spec/lib/hamster/sorted_set/eql_spec.rb +5 -5
- data/spec/lib/hamster/sorted_set/exclusion_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/fetch_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/find_index_spec.rb +10 -2
- data/spec/lib/hamster/sorted_set/first_spec.rb +10 -12
- data/spec/lib/hamster/sorted_set/from_spec.rb +11 -11
- data/spec/lib/hamster/sorted_set/group_by_spec.rb +10 -10
- data/spec/lib/hamster/sorted_set/include_spec.rb +2 -2
- data/spec/lib/hamster/sorted_set/inspect_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/intersect_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/intersection_spec.rb +3 -3
- data/spec/lib/hamster/sorted_set/last_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/map_spec.rb +13 -5
- data/spec/lib/hamster/sorted_set/marshal_spec.rb +3 -3
- data/spec/lib/hamster/sorted_set/maximum_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/minimum_spec.rb +11 -13
- data/spec/lib/hamster/sorted_set/new_spec.rb +23 -3
- data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +2 -2
- data/spec/lib/hamster/sorted_set/{filter_spec.rb → select_spec.rb} +10 -10
- data/spec/lib/hamster/sorted_set/size_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/slice_spec.rb +158 -142
- data/spec/lib/hamster/sorted_set/sorting_spec.rb +3 -3
- data/spec/lib/hamster/sorted_set/subset_spec.rb +2 -2
- data/spec/lib/hamster/sorted_set/superset_spec.rb +2 -2
- data/spec/lib/hamster/sorted_set/take_spec.rb +32 -3
- data/spec/lib/hamster/sorted_set/take_while_spec.rb +4 -4
- data/spec/lib/hamster/sorted_set/to_set_spec.rb +1 -1
- data/spec/lib/hamster/sorted_set/union_spec.rb +2 -2
- data/spec/lib/hamster/sorted_set/up_to_spec.rb +12 -11
- data/spec/lib/hamster/sorted_set/values_at_spec.rb +6 -6
- data/spec/lib/hamster/vector/add_spec.rb +3 -3
- data/spec/lib/hamster/vector/any_spec.rb +1 -1
- data/spec/lib/hamster/vector/assoc_spec.rb +11 -1
- data/spec/lib/hamster/vector/bsearch_spec.rb +10 -2
- data/spec/lib/hamster/vector/clear_spec.rb +3 -3
- data/spec/lib/hamster/vector/combination_spec.rb +4 -4
- data/spec/lib/hamster/vector/compact_spec.rb +2 -2
- data/spec/lib/hamster/vector/compare_spec.rb +3 -3
- data/spec/lib/hamster/vector/concat_spec.rb +2 -2
- data/spec/lib/hamster/vector/copying_spec.rb +1 -1
- data/spec/lib/hamster/vector/delete_at_spec.rb +8 -8
- data/spec/lib/hamster/vector/delete_spec.rb +2 -2
- data/spec/lib/hamster/vector/drop_spec.rb +10 -3
- data/spec/lib/hamster/vector/drop_while_spec.rb +5 -5
- data/spec/lib/hamster/vector/each_index_spec.rb +2 -2
- data/spec/lib/hamster/vector/each_spec.rb +27 -29
- data/spec/lib/hamster/vector/each_with_index_spec.rb +2 -2
- data/spec/lib/hamster/vector/empty_spec.rb +11 -13
- data/spec/lib/hamster/vector/eql_spec.rb +6 -6
- data/spec/lib/hamster/vector/fetch_spec.rb +1 -1
- data/spec/lib/hamster/vector/fill_spec.rb +9 -9
- data/spec/lib/hamster/vector/first_spec.rb +10 -12
- data/spec/lib/hamster/vector/flat_map_spec.rb +51 -0
- data/spec/lib/hamster/vector/flatten_spec.rb +15 -0
- data/spec/lib/hamster/vector/get_spec.rb +4 -4
- data/spec/lib/hamster/vector/group_by_spec.rb +12 -12
- data/spec/lib/hamster/vector/include_spec.rb +2 -2
- data/spec/lib/hamster/vector/insert_spec.rb +2 -2
- data/spec/lib/hamster/vector/inspect_spec.rb +1 -1
- data/spec/lib/hamster/vector/join_spec.rb +5 -5
- data/spec/lib/hamster/vector/last_spec.rb +1 -1
- data/spec/lib/hamster/vector/length_spec.rb +1 -1
- data/spec/lib/hamster/vector/ltlt_spec.rb +2 -2
- data/spec/lib/hamster/vector/map_spec.rb +5 -5
- data/spec/lib/hamster/vector/marshal_spec.rb +2 -2
- data/spec/lib/hamster/vector/maximum_spec.rb +20 -22
- data/spec/lib/hamster/vector/minimum_spec.rb +20 -22
- data/spec/lib/hamster/vector/multiply_spec.rb +4 -4
- data/spec/lib/hamster/vector/partition_spec.rb +5 -5
- data/spec/lib/hamster/vector/permutation_spec.rb +4 -4
- data/spec/lib/hamster/vector/pop_spec.rb +3 -3
- data/spec/lib/hamster/vector/product_spec.rb +10 -10
- data/spec/lib/hamster/vector/put_spec.rb +175 -0
- data/spec/lib/hamster/vector/reduce_spec.rb +5 -57
- data/spec/lib/hamster/vector/{remove_spec.rb → reject_spec.rb} +4 -4
- data/spec/lib/hamster/vector/repeated_combination_spec.rb +4 -4
- data/spec/lib/hamster/vector/repeated_permutation_spec.rb +6 -6
- data/spec/lib/hamster/vector/reverse_each_spec.rb +1 -1
- data/spec/lib/hamster/vector/reverse_spec.rb +1 -1
- data/spec/lib/hamster/vector/rindex_spec.rb +1 -1
- data/spec/lib/hamster/vector/rotate_spec.rb +9 -9
- data/spec/lib/hamster/vector/sample_spec.rb +1 -1
- data/spec/lib/hamster/vector/{filter_spec.rb → select_spec.rb} +8 -8
- data/spec/lib/hamster/vector/set_spec.rb +12 -141
- data/spec/lib/hamster/vector/shift_spec.rb +3 -3
- data/spec/lib/hamster/vector/shuffle_spec.rb +2 -2
- data/spec/lib/hamster/vector/slice_spec.rb +137 -137
- data/spec/lib/hamster/vector/sorting_spec.rb +5 -5
- data/spec/lib/hamster/vector/sum_spec.rb +1 -1
- data/spec/lib/hamster/vector/take_spec.rb +17 -3
- data/spec/lib/hamster/vector/take_while_spec.rb +4 -4
- data/spec/lib/hamster/vector/to_a_spec.rb +1 -1
- data/spec/lib/hamster/vector/to_ary_spec.rb +1 -1
- data/spec/lib/hamster/vector/to_list_spec.rb +2 -1
- data/spec/lib/hamster/vector/to_set_spec.rb +1 -1
- data/spec/lib/hamster/vector/uniq_spec.rb +27 -6
- data/spec/lib/hamster/vector/unshift_spec.rb +3 -3
- data/spec/lib/hamster/vector/values_at_spec.rb +6 -6
- data/spec/lib/hamster/vector/zip_spec.rb +2 -2
- data/spec/lib/load_spec.rb +42 -0
- data/spec/spec_helper.rb +25 -0
- metadata +85 -48
- data/spec/lib/hamster/deque/head_spec.rb +0 -20
- data/spec/lib/hamster/hash/uniq_spec.rb +0 -14
- data/spec/lib/hamster/list/elem_index_spec.rb +0 -36
- data/spec/lib/hamster/list/elem_indices_spec.rb +0 -31
- data/spec/lib/hamster/list/filter_spec.rb +0 -71
- data/spec/lib/hamster/list/find_indices_spec.rb +0 -37
- data/spec/lib/hamster/set/foreach_spec.rb +0 -40
- data/spec/lib/hamster/set/head_spec.rb +0 -31
- data/spec/lib/hamster/set/uniq_spec.rb +0 -14
- data/spec/lib/hamster/sorted_set/construction_spec.rb +0 -29
- data/spec/lib/hamster/vector/exist_spec.rb +0 -70
- data/spec/lib/hamster/vector/exists_spec.rb +0 -70
@@ -1,20 +1,19 @@
|
|
1
|
-
require "forwardable"
|
2
1
|
require "hamster/set"
|
3
2
|
require "hamster/read_copy_update"
|
4
3
|
|
5
4
|
module Hamster
|
6
|
-
|
7
|
-
MutableSet.new(set(*items))
|
8
|
-
end
|
9
|
-
|
5
|
+
# @api private
|
10
6
|
class MutableSet
|
11
|
-
extend Forwardable
|
12
7
|
include ReadCopyUpdate
|
13
8
|
|
9
|
+
def self.[](*items)
|
10
|
+
MutableSet.new(Set[*items])
|
11
|
+
end
|
12
|
+
|
14
13
|
def add(item)
|
15
14
|
transform { |set| set.add(item) }
|
16
15
|
end
|
17
|
-
|
16
|
+
alias :<< :add
|
18
17
|
|
19
18
|
def add?(item)
|
20
19
|
added = false
|
data/lib/hamster/hash.rb
CHANGED
@@ -1,83 +1,76 @@
|
|
1
|
-
require "forwardable"
|
2
|
-
|
3
1
|
require "hamster/immutable"
|
4
2
|
require "hamster/undefined"
|
3
|
+
require "hamster/enumerable"
|
5
4
|
require "hamster/trie"
|
6
5
|
require "hamster/set"
|
7
6
|
require "hamster/vector"
|
7
|
+
require "hamster/associable"
|
8
8
|
|
9
9
|
module Hamster
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# possible, but less efficient. If an existing key is stored again, the new value
|
18
|
-
# will replace that which was previously stored.
|
10
|
+
# A `Hamster::Hash` maps a set of unique keys to corresponding values, much
|
11
|
+
# like a dictionary maps from words to definitions. Given a key, it can store
|
12
|
+
# and retrieve an associated value in constant time. If an existing key is
|
13
|
+
# stored again, the new value will replace the old. It behaves much like
|
14
|
+
# Ruby's built-in Hash, which we will call RubyHash for clarity. Like
|
15
|
+
# RubyHash, two keys that are `#eql?` to each other and have the same
|
16
|
+
# `#hash` are considered identical in a `Hamster::Hash`.
|
19
17
|
#
|
20
|
-
#
|
21
|
-
# for clarity. Like RubyHash, `Hamster::Hash` uses `#hash` and `#eql?` to define
|
22
|
-
# equality between keys. Keys with the same `#hash` code, but which are not `#eql?`
|
23
|
-
# to each other, can coexist in the same `Hamster::Hash`. To retrieve a previously
|
24
|
-
# stored value, the key provided must have the same `#hash` code and be `#eql?`
|
25
|
-
# to the one used for storage.
|
18
|
+
# A `Hamster::Hash` can be created in a couple of ways:
|
26
19
|
#
|
27
|
-
# A `Hamster::Hash` can be created in several ways:
|
28
|
-
#
|
29
|
-
# Hamster.hash('Jane Doe' => 10, 'Jim Doe' => 6)
|
30
20
|
# Hamster::Hash.new(font_size: 10, font_family: 'Arial')
|
31
21
|
# Hamster::Hash[first_name: 'John', last_name: 'Smith']
|
32
22
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# Note that any `Enumerable` object which yields 2-element `[key, value]` arrays
|
37
|
-
# can be used to initialize a `Hamster::Hash`. So this is also possible:
|
23
|
+
# Any `Enumerable` object which yields two-element `[key, value]` arrays
|
24
|
+
# can be used to initialize a `Hamster::Hash`:
|
38
25
|
#
|
39
26
|
# Hamster::Hash.new([[:first_name, 'John'], [:last_name, 'Smith']])
|
40
27
|
#
|
41
|
-
#
|
42
|
-
#
|
28
|
+
# Key/value pairs can be added using {#put}. A new hash is returned and the
|
29
|
+
# existing one is left unchanged:
|
43
30
|
#
|
44
31
|
# hash = Hamster::Hash[a: 100, b: 200]
|
45
|
-
# hash.
|
46
|
-
# hash
|
32
|
+
# hash.put(:c, 500) # => Hamster::Hash[:a => 100, :b => 200, :c => 500]
|
33
|
+
# hash # => Hamster::Hash[:a => 100, :b => 200]
|
47
34
|
#
|
48
|
-
#
|
49
|
-
#
|
35
|
+
# {#put} can also take a block, which is used to calculate the value to be
|
36
|
+
# stored.
|
50
37
|
#
|
51
|
-
# hash.put(:a) {
|
38
|
+
# hash.put(:a) { |current| current + 200 } # => Hamster::Hash[:a => 300, :b => 200]
|
52
39
|
#
|
53
|
-
# Since it is immutable, all methods which you might expect to "modify" a
|
54
|
-
# actually return a new hash and leave the existing one
|
55
|
-
# `hash[key] = value` syntax
|
40
|
+
# Since it is immutable, all methods which you might expect to "modify" a
|
41
|
+
# `Hamster::Hash` actually return a new hash and leave the existing one
|
42
|
+
# unchanged. This means that the `hash[key] = value` syntax from RubyHash
|
43
|
+
# *cannot* be used with `Hamster::Hash`.
|
56
44
|
#
|
57
|
-
#
|
58
|
-
# guarantee any specific iteration order (unlike RubyHash). Likewise, methods like
|
59
|
-
# {#flatten} do not guarantee which order the returned key/value pairs will appear
|
60
|
-
# in.
|
45
|
+
# Nested data structures can easily be updated using {#update_in}:
|
61
46
|
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
47
|
+
# hash = Hamster::Hash["a" => Hamster::Vector[Hamster::Hash["c" => 42]]]
|
48
|
+
# hash.update_in("a", 0, "c") { |value| value + 5 }
|
49
|
+
# # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
|
65
50
|
#
|
66
|
-
#
|
67
|
-
#
|
51
|
+
# While a `Hamster::Hash` can iterate over its keys or values, it does not
|
52
|
+
# guarantee any specific iteration order (unlike RubyHash). Methods like
|
53
|
+
# {#flatten} do not guarantee the order of returned key/value pairs.
|
68
54
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
55
|
+
# Like RubyHash, a `Hamster::Hash` can have a default block which is used
|
56
|
+
# when looking up a key that does not exist. Unlike RubyHash, the default
|
57
|
+
# block will only be passed the missing key, without the hash itself:
|
72
58
|
#
|
59
|
+
# hash = Hamster::Hash.new { |missing_key| missing_key * 10 }
|
60
|
+
# hash[5] # => 50
|
73
61
|
class Hash
|
74
|
-
extend Forwardable
|
75
62
|
include Immutable
|
76
63
|
include Enumerable
|
64
|
+
include Associable
|
77
65
|
|
78
66
|
class << self
|
79
67
|
# Create a new `Hash` populated with the given key/value pairs.
|
80
68
|
#
|
69
|
+
# @example
|
70
|
+
# Hamster::Hash["A" => 1, "B" => 2] # => Hamster::Hash["A" => 1, "B" => 2]
|
71
|
+
# Hamster::Hash[["A", 1], ["B", 2]] # => Hamster::Hash["A" => 1, "B" => 2]
|
72
|
+
#
|
73
|
+
# @param pairs [::Enumerable] initial content of hash. An empty hash is returned if not provided.
|
81
74
|
# @return [Hash]
|
82
75
|
def [](pairs = nil)
|
83
76
|
(pairs.nil? || pairs.empty?) ? empty : new(pairs)
|
@@ -104,6 +97,9 @@ module Hamster
|
|
104
97
|
end
|
105
98
|
end
|
106
99
|
|
100
|
+
# @param pairs [::Enumerable] initial content of hash. An empty hash is returned if not provided.
|
101
|
+
# @yield [key] Optional _default block_ to be stored and used to calculate the default value of a missing key. It will not be yielded during this method. It will not be preserved when marshalling.
|
102
|
+
# @yieldparam key Key that was not present in the hash.
|
107
103
|
def initialize(pairs = nil, &block)
|
108
104
|
@trie = pairs ? Trie[pairs] : EmptyTrie
|
109
105
|
@default = block
|
@@ -118,11 +114,14 @@ module Hamster
|
|
118
114
|
|
119
115
|
# Return the number of key/value pairs in this `Hash`.
|
120
116
|
#
|
117
|
+
# @example
|
118
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].size # => 3
|
119
|
+
#
|
121
120
|
# @return [Integer]
|
122
121
|
def size
|
123
122
|
@trie.size
|
124
123
|
end
|
125
|
-
|
124
|
+
alias :length :size
|
126
125
|
|
127
126
|
# Return `true` if this `Hash` contains no key/value pairs.
|
128
127
|
#
|
@@ -130,34 +129,50 @@ module Hamster
|
|
130
129
|
def empty?
|
131
130
|
@trie.empty?
|
132
131
|
end
|
133
|
-
def_delegator :self, :empty?, :null?
|
134
132
|
|
135
133
|
# Return `true` if the given key object is present in this `Hash`. More precisely,
|
136
134
|
# return `true` if a key with the same `#hash` code, and which is also `#eql?`
|
137
135
|
# to the given key object is present.
|
138
136
|
#
|
137
|
+
# @example
|
138
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key?("B") # => true
|
139
|
+
#
|
139
140
|
# @param key [Object] The key to check for
|
140
141
|
# @return [Boolean]
|
141
142
|
def key?(key)
|
142
143
|
@trie.key?(key)
|
143
144
|
end
|
144
|
-
|
145
|
-
|
146
|
-
|
145
|
+
alias :has_key? :key?
|
146
|
+
alias :include? :key?
|
147
|
+
alias :member? :key?
|
147
148
|
|
148
149
|
# Return `true` if this `Hash` has one or more keys which map to the provided value.
|
149
150
|
#
|
151
|
+
# @example
|
152
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].value?(2) # => true
|
153
|
+
#
|
150
154
|
# @param value [Object] The value to check for
|
151
155
|
# @return [Boolean]
|
152
156
|
def value?(value)
|
153
157
|
each { |k,v| return true if value == v }
|
154
158
|
false
|
155
159
|
end
|
156
|
-
|
160
|
+
alias :has_value? :value?
|
157
161
|
|
158
162
|
# Retrieve the value corresponding to the provided key object. If not found, and
|
159
163
|
# this `Hash` has a default block, the default block is called to provide the
|
160
|
-
# value.
|
164
|
+
# value. Otherwise, return `nil`.
|
165
|
+
#
|
166
|
+
# @example
|
167
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
168
|
+
# h["B"] # => 2
|
169
|
+
# h.get("B") # => 2
|
170
|
+
# h.get("Elephant") # => nil
|
171
|
+
#
|
172
|
+
# # Hamster Hash with a default proc:
|
173
|
+
# h = Hamster::Hash.new("A" => 1, "B" => 2, "C" => 3) { |key| key.size }
|
174
|
+
# h.get("B") # => 2
|
175
|
+
# h.get("Elephant") # => 8
|
161
176
|
#
|
162
177
|
# @param key [Object] The key to look up
|
163
178
|
# @return [Object]
|
@@ -169,7 +184,7 @@ module Hamster
|
|
169
184
|
@default.call(key)
|
170
185
|
end
|
171
186
|
end
|
172
|
-
|
187
|
+
alias :[] :get
|
173
188
|
|
174
189
|
# Retrieve the value corresponding to the given key object, or use the provided
|
175
190
|
# default value or block, or otherwise raise a `KeyError`.
|
@@ -190,6 +205,19 @@ module Hamster
|
|
190
205
|
# @param key [Object] The key to look up
|
191
206
|
# @param default [Object] Object to return if the key is not found
|
192
207
|
#
|
208
|
+
# @example
|
209
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
210
|
+
# h.fetch("B") # => 2
|
211
|
+
# h.fetch("Elephant") # => KeyError: key not found: "Elephant"
|
212
|
+
#
|
213
|
+
# # with a default value:
|
214
|
+
# h.fetch("B", 99) # => 2
|
215
|
+
# h.fetch("Elephant", 99) # => 99
|
216
|
+
#
|
217
|
+
# # with a block:
|
218
|
+
# h.fetch("B") { |key| key.size } # => 2
|
219
|
+
# h.fetch("Elephant") { |key| key.size } # => 8
|
220
|
+
#
|
193
221
|
# @return [Object]
|
194
222
|
def fetch(key, default = Undefined)
|
195
223
|
entry = @trie.get(key)
|
@@ -213,36 +241,70 @@ module Hamster
|
|
213
241
|
# returns will replace the existing value. This is useful for "transforming"
|
214
242
|
# the value associated with a certain key.
|
215
243
|
#
|
216
|
-
# Avoid mutating objects which are used as keys. `String`s are an exception
|
244
|
+
# Avoid mutating objects which are used as keys. `String`s are an exception:
|
217
245
|
# unfrozen `String`s which are used as keys are internally duplicated and
|
218
|
-
# frozen.
|
246
|
+
# frozen. This matches RubyHash's behaviour.
|
247
|
+
#
|
248
|
+
# @example
|
249
|
+
# h = Hamster::Hash["A" => 1, "B" => 2]
|
250
|
+
# h.put("C", 3)
|
251
|
+
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
252
|
+
# h.put("B") { |value| value * 10 }
|
253
|
+
# # => Hamster::Hash["A" => 1, "B" => 20]
|
219
254
|
#
|
220
255
|
# @param key [Object] The key to store
|
221
256
|
# @param value [Object] The value to associate it with
|
222
|
-
# @yield [value] The previously stored value
|
257
|
+
# @yield [value] The previously stored value, or `nil` if none.
|
223
258
|
# @yieldreturn [Object] The new value to store
|
224
259
|
# @return [Hash]
|
225
260
|
def put(key, value = yield(get(key)))
|
226
|
-
|
261
|
+
new_trie = @trie.put(key, value)
|
262
|
+
if new_trie.equal?(@trie)
|
263
|
+
self
|
264
|
+
else
|
265
|
+
self.class.alloc(new_trie, @default)
|
266
|
+
end
|
227
267
|
end
|
228
268
|
|
229
|
-
# Return a new `Hash` with
|
230
|
-
#
|
231
|
-
#
|
269
|
+
# Return a new `Hash` with a deeply nested value modified to the result of
|
270
|
+
# the given code block. When traversing the nested `Hash`es and `Vector`s,
|
271
|
+
# non-existing keys are created with empty `Hash` values.
|
232
272
|
#
|
233
|
-
#
|
234
|
-
#
|
235
|
-
#
|
273
|
+
# The code block receives the existing value of the deeply nested key (or
|
274
|
+
# `nil` if it doesn't exist). This is useful for "transforming" the value
|
275
|
+
# associated with a certain key.
|
276
|
+
#
|
277
|
+
# Note that the original `Hash` and sub-`Hash`es and sub-`Vector`s are left
|
278
|
+
# unmodified; new data structure copies are created along the path wherever
|
279
|
+
# needed.
|
280
|
+
#
|
281
|
+
# @example
|
282
|
+
# hash = Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 42]]]
|
283
|
+
# hash.update_in("a", "b", "c") { |value| value + 5 }
|
284
|
+
# # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
|
285
|
+
#
|
286
|
+
# @param key_path [::Array<Object>] List of keys which form the path to the key to be modified
|
287
|
+
# @yield [value] The previously stored value
|
288
|
+
# @yieldreturn [Object] The new value to store
|
289
|
+
# @return [Hash]
|
290
|
+
|
291
|
+
# An alias for {#put} to match RubyHash's API. Does not support {#put}'s
|
292
|
+
# block form.
|
236
293
|
#
|
294
|
+
# @see #put
|
237
295
|
# @param key [Object] The key to store
|
238
296
|
# @param value [Object] The value to associate it with
|
239
297
|
# @return [Hash]
|
240
298
|
def store(key, value)
|
241
|
-
|
299
|
+
put(key, value)
|
242
300
|
end
|
243
301
|
|
244
|
-
# Return a new `Hash` with
|
245
|
-
#
|
302
|
+
# Return a new `Hash` with `key` removed. If `key` is not present, return
|
303
|
+
# `self`.
|
304
|
+
#
|
305
|
+
# @example
|
306
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].delete("B")
|
307
|
+
# # => Hamster::Hash["A" => 1, "C" => 3]
|
246
308
|
#
|
247
309
|
# @param key [Object] The key to remove
|
248
310
|
# @return [Hash]
|
@@ -251,20 +313,38 @@ module Hamster
|
|
251
313
|
end
|
252
314
|
|
253
315
|
# Call the block once for each key/value pair in this `Hash`, passing the key/value
|
254
|
-
# pair as parameters. No specific iteration order is guaranteed
|
255
|
-
# be stable for any particular `Hash`.
|
316
|
+
# pair as parameters. No specific iteration order is guaranteed, though the order will
|
317
|
+
# be stable for any particular `Hash`.
|
256
318
|
#
|
319
|
+
# @example
|
320
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each { |k, v| puts "k=#{k} v=#{v}" }
|
321
|
+
#
|
322
|
+
# k=A v=1
|
323
|
+
# k=C v=3
|
324
|
+
# k=B v=2
|
325
|
+
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
326
|
+
#
|
327
|
+
# @yield [key, value] Once for each key/value pair.
|
257
328
|
# @return [self]
|
258
329
|
def each(&block)
|
259
330
|
return to_enum if not block_given?
|
260
331
|
@trie.each(&block)
|
261
332
|
self
|
262
333
|
end
|
263
|
-
|
334
|
+
alias :each_pair :each
|
264
335
|
|
265
336
|
# Call the block once for each key/value pair in this `Hash`, passing the key/value
|
266
337
|
# pair as parameters. Iteration order will be the opposite of {#each}.
|
267
338
|
#
|
339
|
+
# @example
|
340
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].reverse_each { |k, v| puts "k=#{k} v=#{v}" }
|
341
|
+
#
|
342
|
+
# k=B v=2
|
343
|
+
# k=C v=3
|
344
|
+
# k=A v=1
|
345
|
+
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
346
|
+
#
|
347
|
+
# @yield [key, value] Once for each key/value pair.
|
268
348
|
# @return [self]
|
269
349
|
def reverse_each(&block)
|
270
350
|
return enum_for(:reverse_each) if not block_given?
|
@@ -273,8 +353,17 @@ module Hamster
|
|
273
353
|
end
|
274
354
|
|
275
355
|
# Call the block once for each key/value pair in this `Hash`, passing the key as a
|
276
|
-
# parameter.
|
356
|
+
# parameter. Ordering guarantees are the same as {#each}.
|
277
357
|
#
|
358
|
+
# @example
|
359
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_key { |k| puts "k=#{k}" }
|
360
|
+
#
|
361
|
+
# k=A
|
362
|
+
# k=C
|
363
|
+
# k=B
|
364
|
+
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
365
|
+
#
|
366
|
+
# @yield [key] Once for each key/value pair.
|
278
367
|
# @return [self]
|
279
368
|
def each_key
|
280
369
|
return enum_for(:each_key) if not block_given?
|
@@ -283,8 +372,17 @@ module Hamster
|
|
283
372
|
end
|
284
373
|
|
285
374
|
# Call the block once for each key/value pair in this `Hash`, passing the value as a
|
286
|
-
# parameter.
|
375
|
+
# parameter. Ordering guarantees are the same as {#each}.
|
376
|
+
#
|
377
|
+
# @example
|
378
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_value { |v| puts "v=#{v}" }
|
287
379
|
#
|
380
|
+
# v=1
|
381
|
+
# v=3
|
382
|
+
# v=2
|
383
|
+
# # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
384
|
+
#
|
385
|
+
# @yield [value] Once for each key/value pair.
|
288
386
|
# @return [self]
|
289
387
|
def each_value
|
290
388
|
return enum_for(:each_value) if not block_given?
|
@@ -296,48 +394,72 @@ module Hamster
|
|
296
394
|
# pair as parameters. The block should return a `[key, value]` array each time.
|
297
395
|
# All the returned `[key, value]` arrays will be gathered into a new `Hash`.
|
298
396
|
#
|
397
|
+
# @example
|
398
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
399
|
+
# h.map { |k, v| ["new-#{k}", v * v] }
|
400
|
+
# # => Hash["new-C" => 9, "new-B" => 4, "new-A" => 1]
|
401
|
+
#
|
402
|
+
# @yield [key, value] Once for each key/value pair.
|
299
403
|
# @return [Hash]
|
300
404
|
def map
|
301
405
|
return enum_for(:map) unless block_given?
|
302
406
|
return self if empty?
|
303
407
|
self.class.new(super, &@default)
|
304
408
|
end
|
305
|
-
|
306
|
-
|
307
|
-
def_delegator :self, :reduce, :foldr
|
409
|
+
alias :collect :map
|
308
410
|
|
309
411
|
# Return a new `Hash` with all the key/value pairs for which the block returns true.
|
310
412
|
#
|
413
|
+
# @example
|
414
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
415
|
+
# h.select { |k, v| v >= 2 }
|
416
|
+
# # => Hamster::Hash["B" => 2, "C" => 3]
|
417
|
+
#
|
418
|
+
# @yield [key, value] Once for each key/value pair.
|
419
|
+
# @yieldreturn Truthy if this pair should be present in the new `Hash`.
|
311
420
|
# @return [Hash]
|
312
|
-
def
|
313
|
-
return enum_for(:
|
314
|
-
derive_new_hash(@trie.
|
421
|
+
def select(&block)
|
422
|
+
return enum_for(:select) unless block_given?
|
423
|
+
derive_new_hash(@trie.select(&block))
|
315
424
|
end
|
425
|
+
alias :find_all :select
|
426
|
+
alias :keep_if :select
|
316
427
|
|
317
428
|
# Yield `[key, value]` pairs until one is found for which the block returns true.
|
318
429
|
# Return that `[key, value]` pair. If the block never returns true, return `nil`.
|
319
430
|
#
|
431
|
+
# @example
|
432
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
433
|
+
# h.find { |k, v| v.even? }
|
434
|
+
# # => ["B", 2]
|
435
|
+
#
|
320
436
|
# @return [Array]
|
437
|
+
# @yield [key, value] At most once for each key/value pair, until the block returns `true`.
|
438
|
+
# @yieldreturn Truthy to halt iteration and return the yielded key/value pair.
|
321
439
|
def find
|
322
440
|
return enum_for(:find) unless block_given?
|
323
441
|
each { |entry| return entry if yield entry }
|
324
442
|
nil
|
325
443
|
end
|
326
|
-
|
327
|
-
|
328
|
-
def_delegator :self, :max, :maximum
|
329
|
-
def_delegator :self, :min, :minimum
|
444
|
+
alias :detect :find
|
330
445
|
|
331
446
|
# Return a new `Hash` containing all the key/value pairs from this `Hash` and
|
332
447
|
# `other`. If no block is provided, the value for entries with colliding keys
|
333
|
-
# will be that from `other`.
|
334
|
-
# determined by
|
335
|
-
# its value in `other`.
|
448
|
+
# will be that from `other`. Otherwise, the value for each duplicate key is
|
449
|
+
# determined by calling the block.
|
336
450
|
#
|
337
451
|
# `other` can be a `Hamster::Hash`, a built-in Ruby `Hash`, or any `Enumerable`
|
338
452
|
# object which yields `[key, value]` pairs.
|
339
453
|
#
|
340
|
-
# @
|
454
|
+
# @example
|
455
|
+
# h1 = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
456
|
+
# h2 = Hamster::Hash["C" => 70, "D" => 80]
|
457
|
+
# h1.merge(h2)
|
458
|
+
# # => Hamster::Hash["C" => 70, "A" => 1, "D" => 80, "B" => 2]
|
459
|
+
# h1.merge(h2) { |key, v1, v2| v1 + v2 }
|
460
|
+
# # => Hamster::Hash["C" => 73, "A" => 1, "D" => 80, "B" => 2]
|
461
|
+
#
|
462
|
+
# @param other [::Enumerable] The collection to merge with
|
341
463
|
# @yieldparam key [Object] The key which was present in both collections
|
342
464
|
# @yieldparam my_value [Object] The associated value from this `Hash`
|
343
465
|
# @yieldparam other_value [Object] The associated value from the other collection
|
@@ -353,17 +475,38 @@ module Hamster
|
|
353
475
|
end
|
354
476
|
end
|
355
477
|
else
|
356
|
-
|
478
|
+
@trie.bulk_put(other)
|
357
479
|
end
|
358
480
|
|
359
481
|
derive_new_hash(trie)
|
360
482
|
end
|
361
|
-
def_delegator :self, :merge, :+
|
362
483
|
|
363
|
-
#
|
364
|
-
#
|
365
|
-
#
|
366
|
-
#
|
484
|
+
# Retrieve the value corresponding to the given key object, or use the provided
|
485
|
+
# default value or block, or otherwise raise a `KeyError`.
|
486
|
+
#
|
487
|
+
# @overload fetch(key)
|
488
|
+
# Retrieve the value corresponding to the given key, or raise a `KeyError`
|
489
|
+
# if it is not found.
|
490
|
+
# @param key [Object] The key to look up
|
491
|
+
# @overload fetch(key) { |key| ... }
|
492
|
+
|
493
|
+
# Return a sorted {Vector} which contains all the `[key, value]` pairs in
|
494
|
+
# this `Hash` as two-element `Array`s.
|
495
|
+
#
|
496
|
+
# @overload sort
|
497
|
+
# Uses `#<=>` to determine sorted order.
|
498
|
+
# @overload sort { |(k1, v1), (k2, v2)| ... }
|
499
|
+
# Uses the block as a comparator to determine sorted order.
|
500
|
+
#
|
501
|
+
# @example
|
502
|
+
# h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
|
503
|
+
# h.sort { |(k1, v1), (k2, v2)| k1.size <=> k2.size }
|
504
|
+
# # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
|
505
|
+
# @yield [(k1, v1), (k2, v2)] Any number of times with different pairs of key/value associations.
|
506
|
+
# @yieldreturn [Integer] Negative if the first pair should be sorted
|
507
|
+
# lower, positive if the latter pair, or 0 if equal.
|
508
|
+
#
|
509
|
+
# @see ::Enumerable#sort
|
367
510
|
#
|
368
511
|
# @return [Vector]
|
369
512
|
def sort
|
@@ -371,11 +514,19 @@ module Hamster
|
|
371
514
|
end
|
372
515
|
|
373
516
|
# Return a {Vector} which contains all the `[key, value]` pairs in this `Hash`
|
374
|
-
# as
|
517
|
+
# as two-element Arrays. The order which the pairs will appear in is determined by
|
375
518
|
# passing each pair to the code block to obtain a sort key object, and comparing
|
376
519
|
# the sort keys using `#<=>`.
|
377
|
-
# See `Enumerable#sort_by`.
|
378
520
|
#
|
521
|
+
# @see ::Enumerable#sort_by
|
522
|
+
#
|
523
|
+
# @example
|
524
|
+
# h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
|
525
|
+
# h.sort_by { |key, value| key.size }
|
526
|
+
# # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
|
527
|
+
#
|
528
|
+
# @yield [key, value] Once for each key/value pair.
|
529
|
+
# @yieldreturn a sort key object for the yielded pair.
|
379
530
|
# @return [Vector]
|
380
531
|
def sort_by
|
381
532
|
Vector.new(super)
|
@@ -383,6 +534,10 @@ module Hamster
|
|
383
534
|
|
384
535
|
# Return a new `Hash` with the associations for all of the given `keys` removed.
|
385
536
|
#
|
537
|
+
# @example
|
538
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
539
|
+
# h.except("A", "C") # => Hamster::Hash["B" => 2]
|
540
|
+
#
|
386
541
|
# @param keys [Array] The keys to remove
|
387
542
|
# @return [Hash]
|
388
543
|
def except(*keys)
|
@@ -390,10 +545,12 @@ module Hamster
|
|
390
545
|
end
|
391
546
|
|
392
547
|
# Return a new `Hash` with only the associations for the `wanted` keys retained.
|
393
|
-
# If any of the `wanted` keys are not present in this `Hash`, they will not be present
|
394
|
-
# in the returned `Hash` either.
|
395
548
|
#
|
396
|
-
# @
|
549
|
+
# @example
|
550
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
551
|
+
# h.slice("B", "C") # => Hamster::Hash["B" => 2, "C" => 3]
|
552
|
+
#
|
553
|
+
# @param wanted [::Enumerable] The keys to retain
|
397
554
|
# @return [Hash]
|
398
555
|
def slice(*wanted)
|
399
556
|
trie = Trie.new(0)
|
@@ -404,6 +561,10 @@ module Hamster
|
|
404
561
|
# Return a {Vector} of the values which correspond to the `wanted` keys.
|
405
562
|
# If any of the `wanted` keys are not present in this `Hash`, they will be skipped.
|
406
563
|
#
|
564
|
+
# @example
|
565
|
+
# h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
|
566
|
+
# h.values_at("B", "A", "D") # => Hamster::Vector[2, 1]
|
567
|
+
#
|
407
568
|
# @param wanted [Array] The keys to retrieve
|
408
569
|
# @return [Vector]
|
409
570
|
def values_at(*wanted)
|
@@ -412,7 +573,11 @@ module Hamster
|
|
412
573
|
Vector.new(array.freeze)
|
413
574
|
end
|
414
575
|
|
415
|
-
# Return a new {Set}
|
576
|
+
# Return a new {Set} containing the keys from this `Hash`.
|
577
|
+
#
|
578
|
+
# @example
|
579
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].keys
|
580
|
+
# # => Hamster::Set["D", "C", "B", "A"]
|
416
581
|
#
|
417
582
|
# @return [Set]
|
418
583
|
def keys
|
@@ -421,14 +586,23 @@ module Hamster
|
|
421
586
|
|
422
587
|
# Return a new {Vector} populated with the values from this `Hash`.
|
423
588
|
#
|
589
|
+
# @example
|
590
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].values
|
591
|
+
# # => Hamster::Vector[2, 3, 2, 1]
|
592
|
+
#
|
424
593
|
# @return [Vector]
|
425
594
|
def values
|
426
595
|
Vector.new(each_value.to_a.freeze)
|
427
596
|
end
|
428
597
|
|
429
|
-
# Return a new `Hash` created by using
|
598
|
+
# Return a new `Hash` created by using keys as values and values as keys.
|
430
599
|
# If there are multiple values which are equivalent (as determined by `#hash` and
|
431
|
-
# `#eql?`), only one out of each group of equivalent values will be
|
600
|
+
# `#eql?`), only one out of each group of equivalent values will be
|
601
|
+
# retained. Which one specifically is undefined.
|
602
|
+
#
|
603
|
+
# @example
|
604
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].invert
|
605
|
+
# # => Hamster::Hash[1 => "A", 3 => "C", 2 => "B"]
|
432
606
|
#
|
433
607
|
# @return [Hash]
|
434
608
|
def invert
|
@@ -447,6 +621,13 @@ module Hamster
|
|
447
621
|
# As a special case, if `level` is 0, each `[key, value]` pair will be a
|
448
622
|
# separate element in the returned {Vector}.
|
449
623
|
#
|
624
|
+
# @example
|
625
|
+
# h = Hamster::Hash["A" => 1, "B" => [2, 3, 4]]
|
626
|
+
# h.flatten
|
627
|
+
# # => Hamster::Vector["A", 1, "B", [2, 3, 4]]
|
628
|
+
# h.flatten(2)
|
629
|
+
# # => Hamster::Vector["A", 1, "B", 2, 3, 4]
|
630
|
+
#
|
450
631
|
# @param level [Integer] The number of times to recursively flatten the `[key, value]` pairs in this `Hash`.
|
451
632
|
# @return [Vector]
|
452
633
|
def flatten(level = 1)
|
@@ -461,6 +642,9 @@ module Hamster
|
|
461
642
|
# When a matching key is found, return the `[key, value]` pair as an array.
|
462
643
|
# Return `nil` if no match is found.
|
463
644
|
#
|
645
|
+
# @example
|
646
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].assoc("B") # => ["B", 2]
|
647
|
+
#
|
464
648
|
# @param obj [Object] The key to search for (using #==)
|
465
649
|
# @return [Array]
|
466
650
|
def assoc(obj)
|
@@ -472,6 +656,9 @@ module Hamster
|
|
472
656
|
# When a matching value is found, return the `[key, value]` pair as an array.
|
473
657
|
# Return `nil` if no match is found.
|
474
658
|
#
|
659
|
+
# @example
|
660
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].rassoc(2) # => ["B", 2]
|
661
|
+
#
|
475
662
|
# @param obj [Object] The value to search for (using #==)
|
476
663
|
# @return [Array]
|
477
664
|
def rassoc(obj)
|
@@ -483,6 +670,9 @@ module Hamster
|
|
483
670
|
# When a matching value is found, return its associated key object.
|
484
671
|
# Return `nil` if no match is found.
|
485
672
|
#
|
673
|
+
# @example
|
674
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key(2) # => "B"
|
675
|
+
#
|
486
676
|
# @param value [Object] The value to search for (using #==)
|
487
677
|
# @return [Object]
|
488
678
|
def key(value)
|
@@ -493,6 +683,10 @@ module Hamster
|
|
493
683
|
# Return a randomly chosen `[key, value]` pair from this `Hash`. If the hash is empty,
|
494
684
|
# return `nil`.
|
495
685
|
#
|
686
|
+
# @example
|
687
|
+
# Hamster::Hash["A" => 1, "B" => 2, "C" => 3].sample
|
688
|
+
# # => ["C", 3]
|
689
|
+
#
|
496
690
|
# @return [Array]
|
497
691
|
def sample
|
498
692
|
@trie.at(rand(size))
|
@@ -537,14 +731,10 @@ module Hamster
|
|
537
731
|
end
|
538
732
|
end
|
539
733
|
|
540
|
-
def_delegator :self, :dup, :uniq
|
541
|
-
def_delegator :self, :dup, :nub
|
542
|
-
def_delegator :self, :dup, :remove_duplicates
|
543
|
-
|
544
734
|
# Return the contents of this `Hash` as a programmer-readable `String`. If all the
|
545
735
|
# keys and values are serializable as Ruby literal strings, the returned string can
|
546
|
-
# be passed to `eval` to reconstitute an equivalent `Hash`.
|
547
|
-
# block (if there is one) will be lost when doing this.
|
736
|
+
# be passed to `eval` to reconstitute an equivalent `Hash`. The default
|
737
|
+
# block (if there is one) will be lost when doing this, however.
|
548
738
|
#
|
549
739
|
# @return [String]
|
550
740
|
def inspect
|
@@ -590,7 +780,7 @@ module Hamster
|
|
590
780
|
end
|
591
781
|
output
|
592
782
|
end
|
593
|
-
|
783
|
+
alias :to_h :to_hash
|
594
784
|
|
595
785
|
# @return [::Hash]
|
596
786
|
# @private
|
@@ -623,9 +813,10 @@ module Hamster
|
|
623
813
|
end
|
624
814
|
end
|
625
815
|
|
626
|
-
# The canonical empty `Hash`. Returned by `
|
816
|
+
# The canonical empty `Hash`. Returned by `Hash[]` when
|
627
817
|
# invoked with no arguments; also returned by `Hash.empty`. Prefer using this
|
628
818
|
# one rather than creating many empty hashes using `Hash.new`.
|
629
819
|
#
|
820
|
+
# @private
|
630
821
|
EmptyHash = Hamster::Hash.empty
|
631
822
|
end
|