hash_math 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -4
- data/.ruby-version +1 -1
- data/.travis.yml +3 -4
- data/CHANGELOG.md +14 -0
- data/README.md +51 -0
- data/hash_math.gemspec +8 -5
- data/lib/hash_math.rb +3 -0
- data/lib/hash_math/matrix.rb +5 -1
- data/lib/hash_math/unpivot.rb +55 -0
- data/lib/hash_math/unpivot/pivot.rb +47 -0
- data/lib/hash_math/unpivot/pivot_set.rb +54 -0
- data/lib/hash_math/version.rb +1 -1
- data/spec/hash_math/unpivot/pivot_spec.rb +53 -0
- data/spec/hash_math/unpivot_spec.rb +121 -0
- metadata +46 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7df04a330a0de007fb2dba40e7deb6b835ad5aebdf0be39dd596c4af6ee52715
|
4
|
+
data.tar.gz: b0277b0818de7dcb5f59a82e46e761bc6afb16c7f74ed3fc5390b9cd6addd6bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73f27b9a0746d605e7471aa14f4b1203894c72064555ed19303acc2e2c4e18169e8365daf20aeb299afc5b3faef9ec0552af04bab8b73fdc59bf9beb8baa2bd8
|
7
|
+
data.tar.gz: bc0eb13e08c690f7506ad413ad4fe1a3d22698cbe8f313efc1af8d62546ca1c0ab2cea4b0ba55f44758661688d9da6e3ff11931aca88a775226bcfb26758315b
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Layout/LineLength:
|
2
6
|
Max: 100
|
3
7
|
|
4
8
|
Metrics/BlockLength:
|
@@ -13,9 +17,6 @@ Metrics/BlockLength:
|
|
13
17
|
Metrics/MethodLength:
|
14
18
|
Max: 25
|
15
19
|
|
16
|
-
AllCops:
|
17
|
-
TargetRubyVersion: 2.3
|
18
|
-
|
19
20
|
Metrics/AbcSize:
|
20
21
|
Max: 16
|
21
22
|
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.6.
|
1
|
+
2.6.6
|
data/.travis.yml
CHANGED
@@ -4,10 +4,9 @@ env:
|
|
4
4
|
language: ruby
|
5
5
|
rvm:
|
6
6
|
# Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
|
7
|
-
- 2.
|
8
|
-
- 2.
|
9
|
-
- 2.
|
10
|
-
- 2.6.3
|
7
|
+
- 2.5.8
|
8
|
+
- 2.6.6
|
9
|
+
- 2.7.1
|
11
10
|
cache: bundler
|
12
11
|
before_script:
|
13
12
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# 1.1.0 (August 13t, 2020)
|
2
|
+
|
3
|
+
Adding:
|
4
|
+
|
5
|
+
* HashMath#Unpivot class and implementation.
|
6
|
+
|
7
|
+
Removing:
|
8
|
+
|
9
|
+
* Support for Ruby < 2.5
|
10
|
+
|
11
|
+
# 1.0.0 (September 18th, 2019)
|
12
|
+
|
13
|
+
Initial release.
|
14
|
+
|
1
15
|
# 1.0.0-alpha (September 16th, 2019)
|
2
16
|
|
3
17
|
Added initial implementation of:
|
data/README.md
CHANGED
@@ -179,6 +179,57 @@ Notes:
|
|
179
179
|
* `#add` will throw a KeyOutOfBoundsError if the key is not found.
|
180
180
|
* key is type-sensitive and works just like Hash keys work.
|
181
181
|
|
182
|
+
### Unpivot: Hash Key Coalescence and Row Extrapolation
|
183
|
+
|
184
|
+
Sometimes the expected interface is column-based, but the actual data store is row-based. This causes an impedance between the input set and the persistable data set. HashMath::Unpivot has the ability to extrapolate one hash (row) into multiple hashes (rows) while unpivoting specific keys into key-value pairs.
|
185
|
+
|
186
|
+
For example: say we have a database table persisting key-value pairs of patient attributes:
|
187
|
+
|
188
|
+
patient_id | field | value
|
189
|
+
---------- | --------------- | ----------
|
190
|
+
2 | first_exam_date | 2020-01-03
|
191
|
+
2 | last_exam_date | 2020-04-05
|
192
|
+
2 | consent_date | 2020-01-02
|
193
|
+
|
194
|
+
But our input data looks like this:
|
195
|
+
|
196
|
+
````ruby
|
197
|
+
patient = {
|
198
|
+
patient_id: 2,
|
199
|
+
first_exam_date: '2020-01-03',
|
200
|
+
last_exam_date: '2020-04-05',
|
201
|
+
consent_date: '2020-01-02'
|
202
|
+
}
|
203
|
+
````
|
204
|
+
|
205
|
+
We could use a HashMath::Unpivot to go from one hash to three hashes:
|
206
|
+
|
207
|
+
````ruby
|
208
|
+
pivot_set = {
|
209
|
+
pivots: [
|
210
|
+
{
|
211
|
+
keys: %i[first_exam_date last_exam_date consent_date],
|
212
|
+
coalesce_key: :field,
|
213
|
+
coalesce_key_value: :value
|
214
|
+
}
|
215
|
+
]
|
216
|
+
}
|
217
|
+
|
218
|
+
rows = HashMath::Unpivot.new(pivot_set).perform(patient)
|
219
|
+
````
|
220
|
+
|
221
|
+
The `rows` variable should now be equivalent to:
|
222
|
+
|
223
|
+
````ruby
|
224
|
+
[
|
225
|
+
{ patient_id: 2, field: :first_exam_date, value: '2020-01-03' },
|
226
|
+
{ patient_id: 2, field: :last_exam_date, value: '2020-04-05' },
|
227
|
+
{ patient_id: 2, field: :consent_date, value: '2020-01-02' }
|
228
|
+
]
|
229
|
+
````
|
230
|
+
|
231
|
+
Note: `HashMath::Unpivot#add` also exists to update an already instantiated object with new pivot_sets.
|
232
|
+
|
182
233
|
## Contributing
|
183
234
|
|
184
235
|
### Development Environment Configuration
|
data/hash_math.gemspec
CHANGED
@@ -19,13 +19,16 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.homepage = 'https://github.com/bluemarblepayroll/hash_math'
|
20
20
|
s.license = 'MIT'
|
21
21
|
|
22
|
-
s.required_ruby_version = '>= 2.
|
22
|
+
s.required_ruby_version = '>= 2.5'
|
23
|
+
|
24
|
+
s.add_dependency('acts_as_hashable', '~>1')
|
23
25
|
|
24
26
|
s.add_development_dependency('guard-rspec', '~>4.7')
|
25
27
|
s.add_development_dependency('pry', '~>0')
|
26
|
-
s.add_development_dependency('
|
28
|
+
s.add_development_dependency('pry-byebug', '~>3')
|
29
|
+
s.add_development_dependency('rake', '~>13.0')
|
27
30
|
s.add_development_dependency('rspec')
|
28
|
-
s.add_development_dependency('rubocop', '~>0.
|
29
|
-
s.add_development_dependency('simplecov', '~>0.
|
30
|
-
s.add_development_dependency('simplecov-console', '~>0.
|
31
|
+
s.add_development_dependency('rubocop', '~>0.88.0')
|
32
|
+
s.add_development_dependency('simplecov', '~>0.18.5')
|
33
|
+
s.add_development_dependency('simplecov-console', '~>0.7.0')
|
31
34
|
end
|
data/lib/hash_math.rb
CHANGED
@@ -7,9 +7,12 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
+
require 'acts_as_hashable'
|
11
|
+
|
10
12
|
require_relative 'hash_math/matrix'
|
11
13
|
require_relative 'hash_math/record'
|
12
14
|
require_relative 'hash_math/table'
|
15
|
+
require_relative 'hash_math/unpivot'
|
13
16
|
|
14
17
|
# Top-level namespace
|
15
18
|
module HashMath
|
data/lib/hash_math/matrix.rb
CHANGED
@@ -40,8 +40,12 @@ module HashMath
|
|
40
40
|
pairs_by_key[key] ||= KeyValuePair.new(key)
|
41
41
|
end
|
42
42
|
|
43
|
+
def make_pair_groups
|
44
|
+
pairs_by_key.values.map(&:pairs)
|
45
|
+
end
|
46
|
+
|
43
47
|
def pair_products
|
44
|
-
pair_groups =
|
48
|
+
pair_groups = make_pair_groups
|
45
49
|
|
46
50
|
products = pair_groups.inject(pair_groups.shift) { |memo, f| memo.product(f) }
|
47
51
|
&.map { |f| f.is_a?(KeyValuePair::Pair) ? [f] : f.flatten } || []
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'unpivot/pivot_set'
|
11
|
+
|
12
|
+
module HashMath
|
13
|
+
# This class has the ability to extrapolate one hash (row) into multiple hashes (rows) while
|
14
|
+
# unpivoting specific keys into key-value pairs.
|
15
|
+
class Unpivot
|
16
|
+
acts_as_hashable
|
17
|
+
extend Forwardable
|
18
|
+
|
19
|
+
attr_reader :pivot_set
|
20
|
+
|
21
|
+
def_delegators :pivot_set, :add
|
22
|
+
|
23
|
+
def initialize(pivot_set = PivotSet.new)
|
24
|
+
@pivot_set = PivotSet.make(pivot_set, nullable: false)
|
25
|
+
|
26
|
+
freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
# The main method for this class that performs the un-pivoting and hash expansion.
|
30
|
+
# Pass in a hash and it will return an array of hashes.
|
31
|
+
def expand(hash)
|
32
|
+
return [hash] unless pivot_set.any?
|
33
|
+
|
34
|
+
all_combinations = pivot_set.expand(hash)
|
35
|
+
|
36
|
+
products = all_combinations.inject(all_combinations.shift) do |memo, array|
|
37
|
+
memo.product(array)
|
38
|
+
end
|
39
|
+
|
40
|
+
recombine(products)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def recombine(products)
|
46
|
+
products.map do |pairs|
|
47
|
+
if pairs.is_a?(Array)
|
48
|
+
pairs.inject(pairs.shift) { |memo, p| memo.merge(p) }
|
49
|
+
else
|
50
|
+
pairs
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module HashMath
|
11
|
+
class Unpivot
|
12
|
+
# A single pivot definition consists of which columns to coalesce and to where.
|
13
|
+
class Pivot
|
14
|
+
acts_as_hashable
|
15
|
+
|
16
|
+
attr_reader :coalesce_key,
|
17
|
+
:coalesce_key_value,
|
18
|
+
:keys
|
19
|
+
|
20
|
+
# keys is an array of keys to include in the un-pivoting.
|
21
|
+
# coalesce_key is the new key to use.
|
22
|
+
# coalesce_key_value is the new key to use for its corresponding values.
|
23
|
+
def initialize(keys:, coalesce_key:, coalesce_key_value:)
|
24
|
+
@keys = Array(keys)
|
25
|
+
@coalesce_key = coalesce_key
|
26
|
+
@coalesce_key_value = coalesce_key_value
|
27
|
+
|
28
|
+
freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
# The most rudimentary portion of the Unpivoting algorithm, this method works on
|
32
|
+
# just one pivot and returns the extrapolated, un-pivoted rows.
|
33
|
+
# Takes two hashes as input:
|
34
|
+
# the first will serve as the prototype for each returned hash
|
35
|
+
# the second will be one to use for value extraction.
|
36
|
+
# Returns an array of hashes.
|
37
|
+
def expand(base_hash, value_hash)
|
38
|
+
keys.map do |key|
|
39
|
+
base_hash.merge(
|
40
|
+
coalesce_key => key,
|
41
|
+
coalesce_key_value => value_hash[key]
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'pivot'
|
11
|
+
|
12
|
+
module HashMath
|
13
|
+
class Unpivot
|
14
|
+
# A set of pivots for an Unpivot class to perform.
|
15
|
+
class PivotSet
|
16
|
+
acts_as_hashable
|
17
|
+
extend Forwardable
|
18
|
+
|
19
|
+
attr_reader :pivots
|
20
|
+
|
21
|
+
def_delegators :pivots, :any?
|
22
|
+
|
23
|
+
def initialize(pivots: [])
|
24
|
+
@pivots = Pivot.array(pivots)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Adds another Pivot configuration object to this objects list of pivots.
|
28
|
+
# Returns self.
|
29
|
+
def add(pivot)
|
30
|
+
tap { pivots << Pivot.make(pivot) }
|
31
|
+
end
|
32
|
+
|
33
|
+
# An aggregation of Pivot#expand. This method will iterate over all pivots
|
34
|
+
# and expand them all out.
|
35
|
+
def expand(hash)
|
36
|
+
base_hash = make_base_hash(hash)
|
37
|
+
|
38
|
+
pivots.map { |pivot| pivot.expand(base_hash, hash) }
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def make_base_hash(hash)
|
44
|
+
keys_to_remove = key_set
|
45
|
+
|
46
|
+
hash.reject { |k, _v| keys_to_remove.include?(k) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def key_set
|
50
|
+
pivots.flat_map(&:keys).to_set
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/hash_math/version.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'spec_helper'
|
11
|
+
|
12
|
+
describe HashMath::Unpivot::Pivot do
|
13
|
+
let(:config) do
|
14
|
+
{
|
15
|
+
keys: %i[first_exam_date last_exam_date consent_date],
|
16
|
+
coalesce_key: :field,
|
17
|
+
coalesce_key_value: :value
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:patient) do
|
22
|
+
{
|
23
|
+
patient_id: 2,
|
24
|
+
first_exam_date: '2020-01-03',
|
25
|
+
last_exam_date: '2020-04-05',
|
26
|
+
consent_date: '2020-01-02'
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
subject { described_class.make(config) }
|
31
|
+
|
32
|
+
describe '#expand' do
|
33
|
+
it 'performs a single un-pivoting' do
|
34
|
+
actual = subject.expand({}, patient)
|
35
|
+
|
36
|
+
expected = [
|
37
|
+
{
|
38
|
+
field: :first_exam_date,
|
39
|
+
value: '2020-01-03'
|
40
|
+
},
|
41
|
+
{
|
42
|
+
field: :last_exam_date,
|
43
|
+
value: '2020-04-05'
|
44
|
+
},
|
45
|
+
{
|
46
|
+
field: :consent_date, value: '2020-01-02'
|
47
|
+
}
|
48
|
+
]
|
49
|
+
|
50
|
+
expect(actual).to match_array(expected)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'spec_helper'
|
11
|
+
|
12
|
+
describe HashMath::Unpivot do
|
13
|
+
let(:a_and_b_pivot) do
|
14
|
+
{
|
15
|
+
keys: %i[a b],
|
16
|
+
coalesce_key: :ab_key,
|
17
|
+
coalesce_key_value: :ab_value
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:cd_and_e_pivot) do
|
22
|
+
{
|
23
|
+
keys: %i[c d e],
|
24
|
+
coalesce_key: :cde_key,
|
25
|
+
coalesce_key_value: :cde_value
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:hash) do
|
30
|
+
{ a: 1, b: 2, c: 3, d: 4, e: 5 }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with no pivots' do
|
34
|
+
it 'returns the inputted hash only' do
|
35
|
+
actual = subject.expand(hash)
|
36
|
+
|
37
|
+
expect(actual).to match_array([hash])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with nil inputted' do
|
42
|
+
it 'returns array with nil' do
|
43
|
+
actual = subject.expand(nil)
|
44
|
+
|
45
|
+
expect(actual).to match_array([nil])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with one pivot' do
|
50
|
+
it 'coalesces two columns into two rows' do
|
51
|
+
subject.add(**a_and_b_pivot)
|
52
|
+
|
53
|
+
expected = [
|
54
|
+
{ ab_key: :a, ab_value: 1, c: 3, d: 4, e: 5 },
|
55
|
+
{ ab_key: :b, ab_value: 2, c: 3, d: 4, e: 5 }
|
56
|
+
]
|
57
|
+
|
58
|
+
actual = subject.expand(hash)
|
59
|
+
|
60
|
+
expect(actual).to eq(expected)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with two pivots' do
|
65
|
+
it 'coalesces five columns into six rows' do
|
66
|
+
subject.add(**a_and_b_pivot).add(**cd_and_e_pivot)
|
67
|
+
|
68
|
+
expected = [
|
69
|
+
{ ab_key: :a, ab_value: 1, cde_key: :c, cde_value: 3 },
|
70
|
+
{ ab_key: :b, ab_value: 2, cde_key: :c, cde_value: 3 },
|
71
|
+
{ ab_key: :a, ab_value: 1, cde_key: :d, cde_value: 4 },
|
72
|
+
{ ab_key: :b, ab_value: 2, cde_key: :d, cde_value: 4 },
|
73
|
+
{ ab_key: :a, ab_value: 1, cde_key: :e, cde_value: 5 },
|
74
|
+
{ ab_key: :b, ab_value: 2, cde_key: :e, cde_value: 5 }
|
75
|
+
]
|
76
|
+
|
77
|
+
actual = subject.expand(hash)
|
78
|
+
|
79
|
+
expect(actual).to match_array expected
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'README examples' do
|
84
|
+
context 'single patient row and one pivot example' do
|
85
|
+
let(:patient) do
|
86
|
+
{
|
87
|
+
patient_id: 2,
|
88
|
+
first_exam_date: '2020-01-03',
|
89
|
+
last_exam_date: '2020-04-05',
|
90
|
+
consent_date: '2020-01-02'
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
let(:pivot_set) do
|
95
|
+
{
|
96
|
+
pivots: [
|
97
|
+
{
|
98
|
+
keys: %i[first_exam_date last_exam_date consent_date],
|
99
|
+
coalesce_key: :field,
|
100
|
+
coalesce_key_value: :value
|
101
|
+
}
|
102
|
+
]
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
subject { HashMath::Unpivot.new(pivot_set) }
|
107
|
+
|
108
|
+
it 'extrapolates one row into N rows (one per column key)' do
|
109
|
+
expected = [
|
110
|
+
{ patient_id: 2, field: :first_exam_date, value: '2020-01-03' },
|
111
|
+
{ patient_id: 2, field: :last_exam_date, value: '2020-04-05' },
|
112
|
+
{ patient_id: 2, field: :consent_date, value: '2020-01-02' }
|
113
|
+
]
|
114
|
+
|
115
|
+
actual = subject.expand(patient)
|
116
|
+
|
117
|
+
expect(actual).to match_array(expected)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash_math
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: acts_as_hashable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: guard-rspec
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,20 +52,34 @@ dependencies:
|
|
38
52
|
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
75
|
+
version: '13.0'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
82
|
+
version: '13.0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rspec
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,42 +100,42 @@ dependencies:
|
|
72
100
|
requirements:
|
73
101
|
- - "~>"
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
103
|
+
version: 0.88.0
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
110
|
+
version: 0.88.0
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: simplecov
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
115
|
- - "~>"
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
117
|
+
version: 0.18.5
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
122
|
- - "~>"
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
124
|
+
version: 0.18.5
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: simplecov-console
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
129
|
- - "~>"
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
131
|
+
version: 0.7.0
|
104
132
|
type: :development
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
136
|
- - "~>"
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
138
|
+
version: 0.7.0
|
111
139
|
description: " This library offers general purpose higher-level data structures
|
112
140
|
that focus on Hash manipulation.\n"
|
113
141
|
email:
|
@@ -136,10 +164,15 @@ files:
|
|
136
164
|
- lib/hash_math/matrix/key_value_pair.rb
|
137
165
|
- lib/hash_math/record.rb
|
138
166
|
- lib/hash_math/table.rb
|
167
|
+
- lib/hash_math/unpivot.rb
|
168
|
+
- lib/hash_math/unpivot/pivot.rb
|
169
|
+
- lib/hash_math/unpivot/pivot_set.rb
|
139
170
|
- lib/hash_math/version.rb
|
140
171
|
- spec/hash_math/matrix_spec.rb
|
141
172
|
- spec/hash_math/record_spec.rb
|
142
173
|
- spec/hash_math/table_spec.rb
|
174
|
+
- spec/hash_math/unpivot/pivot_spec.rb
|
175
|
+
- spec/hash_math/unpivot_spec.rb
|
143
176
|
- spec/spec_helper.rb
|
144
177
|
homepage: https://github.com/bluemarblepayroll/hash_math
|
145
178
|
licenses:
|
@@ -153,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
153
186
|
requirements:
|
154
187
|
- - ">="
|
155
188
|
- !ruby/object:Gem::Version
|
156
|
-
version: 2.
|
189
|
+
version: '2.5'
|
157
190
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
191
|
requirements:
|
159
192
|
- - ">="
|
@@ -168,4 +201,6 @@ test_files:
|
|
168
201
|
- spec/hash_math/matrix_spec.rb
|
169
202
|
- spec/hash_math/record_spec.rb
|
170
203
|
- spec/hash_math/table_spec.rb
|
204
|
+
- spec/hash_math/unpivot/pivot_spec.rb
|
205
|
+
- spec/hash_math/unpivot_spec.rb
|
171
206
|
- spec/spec_helper.rb
|