hash-zip 0.1.20170628
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 +7 -0
- data/.rspec +2 -0
- data/README.md +29 -0
- data/Rakefile +23 -0
- data/lib/hash-zip.rb +26 -0
- data/spec/hash_zip_spec.rb +61 -0
- data/spec/spec_helper.rb +4 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3b0b1c5b98183dd893256d7d8c198cde2b3db20a
|
4
|
+
data.tar.gz: 7ae7a02a3dce79af2d4a491357b662c6239b7fc5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ac4ae7d21866bd55951aa50f84c6c8c07dc46f3c2425c7b36407141d852fbc37367d501be6799c39a4a246468fab85a7e573cd4b72293c0795f152180a00baaa
|
7
|
+
data.tar.gz: 6b8700e6c0477c08f24058c1c67f6e964cb720da9fbd948c0819cc1cb64b7e57532a0711999331e7d1c698f2e18de8cdcc0e053c9fe1fe9f46c0f5271a9c65f7
|
data/.rspec
ADDED
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Implements a much needed `Hash#zip` method.
|
2
|
+
|
3
|
+
## Usage
|
4
|
+
|
5
|
+
You can zip multiple Hashes. Keys in result will be keys in any of the inputs, and values will be Arrays with missing values padded by `nil`s.
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
a = {x: 1, y: 2}
|
9
|
+
b = {y: 3, z: 4}
|
10
|
+
a.zip(b)
|
11
|
+
# returns {x: [1, nil], y: [2, 3], z: [nil, 4]}
|
12
|
+
```
|
13
|
+
|
14
|
+
You can also use it with a block. In such case the return value is `nil`:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
a = {x: 1, y: 2}
|
18
|
+
b = {y: 3, z: 4}
|
19
|
+
a.zip(b) do |key, value_a, value_b|
|
20
|
+
p [key, value_a, value_b]
|
21
|
+
# Yields [:x, 1, nil]
|
22
|
+
# [:y, 2, 3]
|
23
|
+
# [:z, nil, 4]
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
It works with more than one argument (`a.zip(b,c)`) as well as with zero arguments (`a.zip()`).
|
28
|
+
|
29
|
+
If arguments are not `Hash`es, but accept `to_h`, they will be converted automatically before zipping.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
task "default" => "spec"
|
2
|
+
task "test" => "spec"
|
3
|
+
|
4
|
+
desc "Run tests"
|
5
|
+
task "spec" do
|
6
|
+
system "rspec"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Clean up"
|
10
|
+
task "clean" do
|
11
|
+
system "trash hash-zip-*.gem"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Build gem"
|
15
|
+
task "gem:build" do
|
16
|
+
system "gem build hash-zip.gemspec"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Upload gem"
|
20
|
+
task "gem:push" => "gem:build" do
|
21
|
+
gem_file = Dir["hash-zip-*.gem"][-1] or raise "No gem found"
|
22
|
+
system "gem", "push", gem_file
|
23
|
+
end
|
data/lib/hash-zip.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Enumerable#zip is nonsense when applied to Hashes
|
2
|
+
class Hash
|
3
|
+
def zip(*args)
|
4
|
+
sources = [self]
|
5
|
+
args.each do |arg|
|
6
|
+
if arg.is_a?(Hash)
|
7
|
+
sources << arg
|
8
|
+
else
|
9
|
+
sources << arg.to_h
|
10
|
+
end
|
11
|
+
end
|
12
|
+
output_keys = sources.flat_map(&:keys).uniq
|
13
|
+
if block_given?
|
14
|
+
output_keys.each do |key|
|
15
|
+
yield(key, *sources.map{|source| source[key]})
|
16
|
+
end
|
17
|
+
nil
|
18
|
+
else
|
19
|
+
result = {}
|
20
|
+
output_keys.each do |key|
|
21
|
+
result[key] = sources.map{|source| source[key]}
|
22
|
+
end
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
describe "Hash#zip" do
|
4
|
+
it "zips itself" do
|
5
|
+
a = {x: 1,
|
6
|
+
y: 2, z: 3}
|
7
|
+
expect(a.zip).to eq({
|
8
|
+
x: [1], y: [2], z: [3]
|
9
|
+
})
|
10
|
+
end
|
11
|
+
|
12
|
+
it "zips two Hashes" do
|
13
|
+
a = {x: 1, y: 2, z: 3}
|
14
|
+
b = {x: 4, z: 5, w: 6}
|
15
|
+
expect(a.zip(b)).to eq({
|
16
|
+
x: [1,4], y: [2,nil], z: [3,5], w: [nil,6]
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
it "zips multiple Hashes, in source order" do
|
21
|
+
a = {a: 1, ab: 2, ac: 3, abc: 4 }
|
22
|
+
b = {b: 5, ab: 6, bc: 7, abc: 8 }
|
23
|
+
c = {c: 9, ac: 10, bc: 11, abc: 12 }
|
24
|
+
expect(a.zip(b, c)).to eq({
|
25
|
+
# All 7 cobinations
|
26
|
+
a: [1,nil,nil],
|
27
|
+
b: [nil,5,nil],
|
28
|
+
c: [nil,nil,9],
|
29
|
+
ab: [2,6,nil],
|
30
|
+
ac: [3,nil,10],
|
31
|
+
bc: [nil,7,11],
|
32
|
+
abc: [4,8,12],
|
33
|
+
})
|
34
|
+
expect(a.zip(b, c).keys).to eq([
|
35
|
+
:a, :ab, :ac, :abc, :b, :bc, :c
|
36
|
+
])
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns nil and yields for each item when passed a block" do
|
40
|
+
a = {x: 1, y: 2, z: 3}
|
41
|
+
b = {x: 4, z: 5, w: 6}
|
42
|
+
calls = []
|
43
|
+
expect(a.zip(b){|*args|
|
44
|
+
calls << args
|
45
|
+
}).to eq(nil)
|
46
|
+
expect(calls).to eq([
|
47
|
+
[:x, 1, 4],
|
48
|
+
[:y, 2, nil],
|
49
|
+
[:z, 3, 5],
|
50
|
+
[:w, nil, 6],
|
51
|
+
])
|
52
|
+
end
|
53
|
+
|
54
|
+
it "converts other arguments to Hashes" do
|
55
|
+
a = {x: 1, y: 2, z: 3}
|
56
|
+
b = OpenStruct.new(x: 4, z: 5, w: 6)
|
57
|
+
expect(a.zip(b)).to eq({
|
58
|
+
x: [1,4], y: [2,nil], z: [3,5], w: [nil,6]
|
59
|
+
})
|
60
|
+
end
|
61
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hash-zip
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.20170628
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tomasz Wegrzanowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Zip two or more Hashes
|
56
|
+
email: Tomasz.Wegrzanowski@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ".rspec"
|
62
|
+
- README.md
|
63
|
+
- Rakefile
|
64
|
+
- lib/hash-zip.rb
|
65
|
+
- spec/hash_zip_spec.rb
|
66
|
+
- spec/spec_helper.rb
|
67
|
+
homepage: https://github.com/taw/hash-zip
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.5.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Hash#zip method
|
91
|
+
test_files: []
|