hamster 1.0.1.pre.rc3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|