hmap 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b91ede0c8bd571c77da15568b4418141005fd68b
4
- data.tar.gz: 5d3be03169ec696f3a4c5787a54eed3a7a82e4f1
2
+ SHA256:
3
+ metadata.gz: 77e9c393f40df641e51a65b9279fc479c5b3e85bb90e74cd6d13a836147c1b56
4
+ data.tar.gz: f1f9f8c51498c80c4de446917dc60462aa020e74a5721684de983d5b2a728211
5
5
  SHA512:
6
- metadata.gz: 4490aad3efaa67f76f58fd9af4a61e5cf26c919140ecef9b11ac637b37d4b763b191efc84c218d7e6e3e7e0441deaff432201014756754e64384d16e6daadf7c
7
- data.tar.gz: 2b443f56320051e2f824eb147de39ed6ecb8b9559041cee6692ed6986ad57b13078503c40b3206e409f4a682c3779977d4d13f110b24d3073380967f05a474fb
6
+ metadata.gz: e925a388dcc787b0b5413d894b363e65f09ebdadf3dd3e25f9f33430421f5b350e494b1aed3d896ad11165555b72a711cd4c8488556dc539b82d9b12191684a2
7
+ data.tar.gz: 98b1d1082abf8af745cda978df664ecfd0565d685beb835ed0e4fd2fd68278d47ef969068d566de061c26086e1aef4492a7e7da29520885c232d99edcd3de68c
data/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ ### 1.1.0 (2026-11-03)
2
+ - require Ruby >= 3.2
3
+ - fix FrozenError from hmap, kmap, and vmap on frozen hashes
4
+ - raise ArgumentError when called without a block
5
+ - hmap and Hash.hmap raise on malformed pairs, e.g. [key], instead of filling in a nil value
6
+ - kmap and vmap pass the key and value to blocks with an optional second param, e.g. |k, v = nil|
7
+
8
+ ### 1.0.1 (2024-07-12)
9
+ - fix changelog
10
+ - rebuild
11
+ - codecov
12
+ - readme
13
+ - upgrades
14
+ - update libs
15
+
16
+ ### 1.0.0, 2018-12-03
17
+ - launch
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hmap (1.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ debug (1.11.1)
10
+ irb (~> 1.10)
11
+ reline (>= 0.3.8)
12
+ diff-lcs (1.6.2)
13
+ erb (6.0.7)
14
+ io-console (0.9.5)
15
+ irb (1.18.0)
16
+ pp (>= 0.6.0)
17
+ prism (>= 1.3.0)
18
+ rdoc (>= 4.0.0)
19
+ reline (>= 0.4.2)
20
+ logger (1.7.0)
21
+ pp (0.6.4)
22
+ prettyprint
23
+ prettyprint (0.2.1)
24
+ prism (2.1.0)
25
+ rbs (4.2.0)
26
+ logger
27
+ prism (>= 1.6.0)
28
+ tsort
29
+ rdoc (8.1.0)
30
+ erb
31
+ prism (>= 1.6.0)
32
+ rbs (>= 4.0.0)
33
+ tsort
34
+ reline (0.7.0)
35
+ io-console (~> 0.5)
36
+ rspec (3.13.2)
37
+ rspec-core (~> 3.13.0)
38
+ rspec-expectations (~> 3.13.0)
39
+ rspec-mocks (~> 3.13.0)
40
+ rspec-core (3.13.6)
41
+ rspec-support (~> 3.13.0)
42
+ rspec-debugging (0.0.5)
43
+ debug (>= 1.10)
44
+ rspec-core (>= 3.10)
45
+ rspec-expectations (3.13.5)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.13.0)
48
+ rspec-mocks (3.13.8)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.13.0)
51
+ rspec-support (3.13.7)
52
+ simplecov (1.3.2)
53
+ tsort (0.2.0)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ debug (>= 1)
60
+ hmap!
61
+ rspec (>= 3.10)
62
+ rspec-debugging
63
+ simplecov (>= 0.22)
64
+
65
+ BUNDLED WITH
66
+ 2.5.15
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Daniel Pepper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ Hmap
2
+ ======
3
+
4
+ Improved Hash mapping functions
5
+
6
+ ### Install
7
+ ```gem install hmap```
8
+
9
+
10
+ ### Usage
11
+ #### Hash.map
12
+ Create a Hash using an Enumerable by mapping its items into corresponding hash values
13
+ ```ruby
14
+ Hash.map [:a, :bb, :ccc] {|v| v.length }
15
+ => { a: 1, bb: 2, ccc: 3 }
16
+ ```
17
+
18
+ #### hmap
19
+ Map an Enumerable into a Hash, like Hash[obj.map ... ]
20
+ ```ruby
21
+ Hash.hmap [ 1, 2, 3 ] { |v| [ v, v * 2 ] }
22
+ => { 1 => 2, 2 => 4, 3 => 6 }
23
+
24
+ {
25
+ 'a' => 1,
26
+ 'b' => 2,
27
+ 'c' => 3,
28
+ }.hmap {|k, v| [ k * v, v ** 2 ] }
29
+ => { 'a' => 1, 'bb' => 4, 'ccc' => 9 }
30
+ ```
31
+
32
+ #### vmap
33
+ Transform the values of a Hash
34
+ ```ruby
35
+ {
36
+ a: 1,
37
+ b: 2,
38
+ c: 3,
39
+ }.vmap {|v| v * 2 }
40
+ => { a: 2, b: 4, c: 6 }
41
+
42
+ {
43
+ a: 1,
44
+ b: 2,
45
+ c: 3,
46
+ }.vmap &:to_s
47
+ => { a: '1', b: '2', c: '3' }
48
+ ```
49
+
50
+ #### kmap
51
+ Transform the keys of a Hash
52
+ ```ruby
53
+ {
54
+ 'a' => 1,
55
+ 'b' => 2,
56
+ 'c' => 3,
57
+ }.kmap {|k, v| k * v }
58
+ => { 'a' => 1, 'bb' => 2, 'ccc' => 3 }
59
+
60
+ {
61
+ 'a' => 1,
62
+ 'b' => 2,
63
+ 'c' => 3,
64
+ }.kmap &:to_sym
65
+ => { a: 1, b: 2, c: 3 }
66
+ ```
67
+
68
+
69
+ ##
70
+ Thanks to [J. Pablo Fernández](https://github.com/pupeno/hmap)
71
+
72
+ ----
73
+ ![Gem](https://img.shields.io/gem/dt/hmap?style=plastic)
74
+ [![codecov](https://codecov.io/gh/dpep/rb_hmap/branch/main/graph/badge.svg)](https://codecov.io/gh/dpep/rb_hmap)
data/hmap.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ require_relative "lib/hmap/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.authors = ["Daniel Pepper"]
5
+ s.description = "Improved Hash mapping functions"
6
+ s.files = `git ls-files * ":!:spec"`.split("\n")
7
+ s.homepage = "https://github.com/dpep/rb_hmap"
8
+ s.license = "MIT"
9
+ s.name = "hmap"
10
+ s.summary = "Hmap"
11
+ s.version = Hmap::VERSION
12
+
13
+ s.required_ruby_version = ">= 3.2"
14
+
15
+ s.add_development_dependency "debug", ">= 1"
16
+ s.add_development_dependency "rspec", ">= 3.10"
17
+ s.add_development_dependency "rspec-debugging"
18
+ s.add_development_dependency "simplecov", ">= 0.22"
19
+ end
data/lib/hmap/hmap.rb CHANGED
@@ -1,65 +1,66 @@
1
- class Hash
1
+ module Hmap
2
+ # create Hash from given keys and mapped values
3
+ def map(obj, &block)
4
+ raise ArgumentError, "no block given" unless block
2
5
 
3
- class << self
4
-
5
- # create Hash from given keys and mapped values
6
- def map(obj, &block)
7
- res = obj.map do |*args|
8
- block.call(*args)
9
- end
10
-
11
- Hash[obj.zip res]
12
- end
13
-
14
-
15
- # map an Enumerable into a Hash, like Hash[obj.map ... ]
16
- def hmap(obj, &block)
17
- Hash[
18
- obj.map do |*args|
19
- block.call(*args)
20
- end.compact
21
- ]
22
- end
6
+ obj.zip(obj.map(&block)).to_h
7
+ end
23
8
 
24
- end # class << self
9
+ # map an Enumerable into a Hash, like obj.map { ... }.to_h
10
+ def hmap(obj, &block)
11
+ raise ArgumentError, "no block given" unless block
25
12
 
13
+ obj.map(&block).compact.to_h
14
+ end
26
15
 
27
- # map the block's results back to a hash
28
- def hmap(&block)
29
- clone.hmap!(&block)
16
+ # call with (key, value) if the block takes both, else just the one
17
+ def self.yield_pair(block, one, key, value)
18
+ positional = block.parameters.count { |type, _| type == :req || type == :opt }
19
+ positional >= 2 ? block.call(key, value) : block.call(one)
30
20
  end
31
21
 
32
- def hmap!(&block)
33
- data = Hash.hmap(self, &block)
34
- clear
35
- merge! data
22
+ def self.extended(base)
23
+ base.include(InstanceMethods)
36
24
  end
37
25
 
26
+ module InstanceMethods
27
+ # map the block's results back to a hash
28
+ def hmap(&block)
29
+ dup.hmap!(&block)
30
+ end
38
31
 
39
- # map keys, but preserve associated values
40
- # ie. http://apidock.com/rails/v4.2.7/Hash/transform_keys
41
- def kmap(&block)
42
- clone.kmap!(&block)
43
- end
32
+ def hmap!(&block)
33
+ data = Hash.hmap(self, &block)
34
+ clear
35
+ merge! data
36
+ end
44
37
 
45
- def kmap!(&block)
46
- hmap! do |k, v|
47
- [ block.arity <= 1 ? block.call(k) : block.call(k, v), v ]
38
+ # map keys, but preserve associated values
39
+ # ie. http://apidock.com/rails/v4.2.7/Hash/transform_keys
40
+ def kmap(&block)
41
+ dup.kmap!(&block)
48
42
  end
49
- end
50
43
 
44
+ def kmap!(&block)
45
+ raise ArgumentError, "no block given" unless block
51
46
 
52
- # map values, but preserve associated keys
53
- # ie. http://apidock.com/rails/v4.2.7/Hash/transform_values
54
- def vmap(&block)
55
- clone.vmap!(&block)
56
- end
47
+ hmap! do |k, v|
48
+ [ Hmap.yield_pair(block, k, k, v), v ]
49
+ end
50
+ end
57
51
 
58
- def vmap!(&block)
59
- each do |k, v|
60
- self[k] = block.arity <= 1 ? block.call(v) : block.call(k, v)
52
+ # map values, but preserve associated keys
53
+ # ie. http://apidock.com/rails/v4.2.7/Hash/transform_values
54
+ def vmap(&block)
55
+ dup.vmap!(&block)
61
56
  end
62
- end
63
57
 
58
+ def vmap!(&block)
59
+ raise ArgumentError, "no block given" unless block
64
60
 
61
+ each do |k, v|
62
+ self[k] = Hmap.yield_pair(block, v, k, v)
63
+ end
64
+ end
65
+ end
65
66
  end
@@ -0,0 +1,3 @@
1
+ module Hmap
2
+ VERSION = "1.1.0"
3
+ end
data/lib/hmap.rb CHANGED
@@ -1,6 +1,4 @@
1
1
  require_relative 'hmap/hmap'
2
+ require_relative 'hmap/version'
2
3
 
3
-
4
- module Hmap
5
- VERSION = '1.0.0'
6
- end
4
+ Hash.extend(Hmap)
metadata CHANGED
@@ -1,45 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pepper
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2018-12-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: byebug
13
+ name: debug
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '0'
18
+ version: '1'
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '0'
25
+ version: '1'
27
26
  - !ruby/object:Gem::Dependency
28
- name: minitest
27
+ name: rspec
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '0'
32
+ version: '3.10'
34
33
  type: :development
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '0'
39
+ version: '3.10'
41
40
  - !ruby/object:Gem::Dependency
42
- name: rake
41
+ name: rspec-debugging
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - ">="
@@ -52,20 +51,38 @@ dependencies:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: simplecov
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0.22'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0.22'
55
68
  description: Improved Hash mapping functions
56
- email:
57
69
  executables: []
58
70
  extensions: []
59
71
  extra_rdoc_files: []
60
72
  files:
73
+ - CHANGELOG.md
74
+ - Gemfile
75
+ - Gemfile.lock
76
+ - LICENSE.txt
77
+ - README.md
78
+ - hmap.gemspec
61
79
  - lib/hmap.rb
62
80
  - lib/hmap/hmap.rb
63
- - test/test_hmap.rb
81
+ - lib/hmap/version.rb
64
82
  homepage: https://github.com/dpep/rb_hmap
65
83
  licenses:
66
84
  - MIT
67
85
  metadata: {}
68
- post_install_message:
69
86
  rdoc_options: []
70
87
  require_paths:
71
88
  - lib
@@ -73,17 +90,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
90
  requirements:
74
91
  - - ">="
75
92
  - !ruby/object:Gem::Version
76
- version: '0'
93
+ version: '3.2'
77
94
  required_rubygems_version: !ruby/object:Gem::Requirement
78
95
  requirements:
79
96
  - - ">="
80
97
  - !ruby/object:Gem::Version
81
98
  version: '0'
82
99
  requirements: []
83
- rubyforge_project:
84
- rubygems_version: 2.6.11
85
- signing_key:
100
+ rubygems_version: 4.0.16
86
101
  specification_version: 4
87
102
  summary: Hmap
88
- test_files:
89
- - test/test_hmap.rb
103
+ test_files: []
data/test/test_hmap.rb DELETED
@@ -1,279 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'hmap'
3
-
4
-
5
- class HmapTest < Minitest::Test
6
-
7
- def test_Hash_map
8
- data = {
9
- c: 2,
10
- b: 3,
11
- a: 1,
12
- }
13
-
14
- assert_equal(
15
- data,
16
- Hash.map(data.keys) {|x| data[x]}
17
- )
18
-
19
- assert_equal(
20
- {},
21
- Hash.map([]) {|x| nil}
22
- )
23
-
24
- assert_equal(
25
- {
26
- 1 => nil,
27
- 2 => nil,
28
- 3 => nil,
29
- },
30
- Hash.map([1,2,3]) {|x| nil}
31
- )
32
-
33
- assert_equal(
34
- {
35
- 1 => false,
36
- 2 => false,
37
- 3 => true,
38
- },
39
- Hash.map([1,2,3]) {|x| x > 2 }
40
- )
41
-
42
- assert_equal(
43
- { 1 => [ 2, 3 ] },
44
- Hash.map([1]) {|x| [ 2, 3 ] }
45
- )
46
- end
47
-
48
-
49
- def test_Hash_hmap
50
- data = {
51
- c: 2,
52
- b: 3,
53
- a: 1,
54
- }
55
-
56
- assert_equal(
57
- data,
58
- Hash.hmap(data) {|k, v| [k, v]}
59
- )
60
-
61
- assert_equal(
62
- { a: 2, b: 6, c: 4 },
63
- Hash.hmap(data) {|k, v| [k, v * 2]}
64
- )
65
-
66
- assert_equal(
67
- { 1 => 2, 2 => 4 },
68
- Hash.hmap([1, 2]) {|x| [ x, x * 2 ] }
69
- )
70
-
71
- assert_equal(
72
- data,
73
- Hash.hmap(data.keys) {|x| [x, data[x]]}
74
- )
75
-
76
- assert_equal(
77
- { nil => 3 },
78
- Hash.hmap([1,2,3]) {|x| [nil, x]}
79
- )
80
-
81
- assert_equal(
82
- {},
83
- Hash.hmap([]) {|x| nil}
84
- )
85
-
86
- assert_equal(
87
- {},
88
- Hash.hmap([1, 2, 3]) {|x| nil}
89
- )
90
- end
91
-
92
-
93
- def test_hmap
94
- data = {
95
- c: 2,
96
- b: 3,
97
- a: 1,
98
- }
99
-
100
- assert_equal(
101
- {
102
- c: 4,
103
- b: 6,
104
- a: 2,
105
- },
106
- data.hmap {|k, v| [k, v * 2]}
107
- )
108
-
109
- assert_equal(
110
- {
111
- cc: 4,
112
- bb: 6,
113
- aa: 2,
114
- },
115
- data.hmap {|k, v| [(k.to_s * 2).to_sym, v * 2]}
116
- )
117
-
118
- assert_equal(
119
- {},
120
- {}.hmap {|k, v| [k, v * 2]}
121
- )
122
-
123
- assert_equal(
124
- {},
125
- {a: 1}.hmap {|k, v| nil}
126
- )
127
-
128
-
129
- assert_equal(
130
- {
131
- c: 4,
132
- b: 6,
133
- a: 2,
134
- },
135
- data.hmap! {|k, v| [k, v * 2]}
136
- )
137
- assert_equal(
138
- {
139
- c: 4,
140
- b: 6,
141
- a: 2,
142
- },
143
- data
144
- )
145
- end
146
-
147
-
148
- def test_kmap
149
- data = {
150
- 'a' => 1,
151
- 'b' => 2,
152
- 'c' => 3,
153
- }
154
-
155
- assert_equal(
156
- data,
157
- data.kmap(&:to_s)
158
- )
159
-
160
- assert_equal(
161
- {
162
- 'aa' => 1,
163
- 'bb' => 2,
164
- 'cc' => 3,
165
- },
166
- data.kmap {|k| k * 2}
167
- )
168
-
169
- assert_equal(
170
- {
171
- 'aa' => 1,
172
- 'bb' => 2,
173
- 'cc' => 3,
174
- },
175
- data.kmap {|k, v| k * 2}
176
- )
177
-
178
- assert_equal(
179
- {
180
- 'aa' => 1,
181
- 'bb' => 2,
182
- 'cc' => 3,
183
- },
184
- data.kmap! {|k, v| k * 2}
185
- )
186
- assert_equal(
187
- {
188
- 'aa' => 1,
189
- 'bb' => 2,
190
- 'cc' => 3,
191
- },
192
- data
193
- )
194
- end
195
-
196
-
197
- def test_vmap
198
- data = {
199
- a: 1,
200
- b: 2,
201
- c: 3,
202
- }
203
-
204
- assert_equal(
205
- {
206
- a: 1.0,
207
- b: 2.0,
208
- c: 3.0,
209
- },
210
- data.vmap(&:to_f)
211
- )
212
-
213
- assert_equal(
214
- {
215
- a: 2,
216
- b: 4,
217
- c: 6,
218
- },
219
- data.vmap {|v| v * 2}
220
- )
221
-
222
- assert_equal(
223
- {
224
- a: 2,
225
- b: 4,
226
- c: 6,
227
- },
228
- data.vmap {|k, v| v * 2}
229
- )
230
-
231
- assert_equal(
232
- {
233
- a: :a,
234
- b: :b,
235
- c: :c,
236
- },
237
- data.vmap {|k, v| k}
238
- )
239
-
240
-
241
- assert_equal(
242
- {
243
- a: 2,
244
- b: 4,
245
- c: 6,
246
- },
247
- data.vmap! {|v| v * 2}
248
- )
249
- assert_equal(
250
- {
251
- a: 2,
252
- b: 4,
253
- c: 6,
254
- },
255
- data
256
- )
257
- end
258
-
259
-
260
- def test_default_value
261
- data = Hash.new 123
262
-
263
- assert_equal(
264
- 123,
265
- data.kmap {|v| nil }[:abc]
266
- )
267
-
268
- assert_equal(
269
- 123,
270
- data.vmap {|v| nil }[:abc]
271
- )
272
-
273
- assert_equal(
274
- 123,
275
- data.hmap {|v| nil }[:abc]
276
- )
277
- end
278
-
279
- end