hash_pivot 0.1.0 → 0.3.1

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
2
  SHA256:
3
- metadata.gz: 580ffb47923a02141676ab7cc6174e410e993aa49d53e3a7c02f994926433638
4
- data.tar.gz: 8280b0020a220ed46df11bcb8a557f13ef6c8c0be99e319d3ee6716751120dc8
3
+ metadata.gz: 871d8c1d4c6a26913eb825057ee2823b54e9919c5a8faceadc008064fd239243
4
+ data.tar.gz: 4a5c03ee17d1ab10a11873f5b56419de12fadeaa6a34695e8eb1d3fd48f0d93e
5
5
  SHA512:
6
- metadata.gz: 94a17744698e9b22fe9c084983d6c2c8a10c123c160f2389d583791884edf08045fbf3c6d624c65e8c7facf4b34e375ef4faa75c6d6123bb6f0fb4ac708c05a7
7
- data.tar.gz: aa168215bbc6fcd46e3bfc93b5cb74e360bed7e511084d359bb9de624210359fea0f142cda76c65b93805ec3b2a1f258fecea2592957769e09ca33f83548cebc
6
+ metadata.gz: b4c7fcd39a18b07f16c8b7facaeb42fdb76969d42879a0c663789458f007692233c9cdb4d4cb6d685d17877b8688e2f17f431c263c8578e1aad67f9b18d56f57
7
+ data.tar.gz: 9fa1e4cb4becd504a2832dcdf5d221709340a23e39ea9c35d917f797949b1768833675fc8e8874b848bce572f0fd84377d4699de6fdd7829e3153413c216421f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2022-06-25
3
+ ## [0.3.1] - 2022-06-28
4
+
5
+ - Refactoring code
6
+ - Add document url
7
+
8
+ ## [0.3.0] - 2022-06-26
9
+
10
+ - Replace Column with label if Hash is given for pivot_kinds.
11
+ - Update README for label replacing.
12
+
13
+ ## [0.2.0] - 2022-06-26
14
+
15
+ - Add usage examples in README.
16
+ - Fix CHANGELOG.md url.
17
+
18
+ ## [0.1.0] - 2022-06-26
4
19
 
5
20
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hash_pivot (0.1.0)
4
+ hash_pivot (0.3.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  # HashPivot
4
4
 
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/hash_pivot`. To experiment with that code, run `bin/console` for an interactive prompt.
6
-
7
- TODO: Delete this and the text above, and describe your gem
5
+ Pivot Array of Hash or Array of Struct or ActiveRecord::Relation.
8
6
 
9
7
  ## Installation
10
8
 
@@ -18,7 +16,165 @@ If bundler is not being used to manage dependencies, install the gem by executin
18
16
 
19
17
  ## Usage
20
18
 
21
- TODO: Write usage instructions here
19
+ ### Pivot Array of Hash
20
+
21
+ #### Prepare data
22
+
23
+ Prepare Array of Hash.
24
+
25
+ id | role | team | age
26
+ -- | -- | -- | --
27
+ 1 | guest | rabbit | 1
28
+ 2 | guest | mouse | 2
29
+ 3 | guest | rabbit | 3
30
+ 4 | admin | mouse | 4
31
+
32
+ ```ruby
33
+ data = [
34
+ { id: 1, role: 'guest', team: 'rabbit', age: 1 },
35
+ { id: 2, role: 'guest', team: 'mouse', age: 2 },
36
+ { id: 3, role: 'guest', team: 'rabbit', age: 3 },
37
+ { id: 4, role: 'admin', team: 'mouse', age: 4 }
38
+ ]
39
+ ```
40
+
41
+ #### Basic usage
42
+
43
+ Grouping by `:role` and pivot in `:team`. Pivot column is `rabbit or mouse` .
44
+
45
+ ```ruby
46
+ HashPivot.pivot(data, :role, :team, %w[rabbit mouse])
47
+
48
+ # [{ :role => "guest",
49
+ # "rabbit" => [{ :id => 1, :role => "guest", :team => "rabbit", :age => 1 }, { :id => 3, :role => "guest", :team => "rabbit", :age => 3 }],
50
+ # "mouse" => [{ :id => 2, :role => "guest", :team => "mouse", :age => 2 }] },
51
+ # { :role => "admin", "rabbit" => [], "mouse" => [{ :id => 4, :role => "admin", :team => "mouse", :age => 4 }] }]
52
+ ```
53
+
54
+ role | rabbit | mouse
55
+ -- | -- | --
56
+ guest | {1 guest rabbit 1} {3 guest rabbit 3} | {2 guest mouse 2}
57
+ admin |   | {4 admin mouse 4}
58
+
59
+ Grouping by `:role` and pivot in `:team`.
60
+
61
+ Pivot column is nil. This means that pivot column is automatically configured.
62
+
63
+ ```ruby
64
+ HashPivot.pivot(data, :role, :team, nil)
65
+
66
+ # [{ :role => "guest",
67
+ # "rabbit" => [{ :id => 1, :role => "guest", :team => "rabbit", :age => 1 }, { :id => 3, :role => "guest", :team => "rabbit", :age => 3 }],
68
+ # "mouse" => [{ :id => 2, :role => "guest", :team => "mouse", :age => 2 }] },
69
+ # { :role => "admin", "mouse" => [{ :id => 4, :role => "admin", :team => "mouse", :age => 4 }] }]
70
+ ```
71
+
72
+ #### Pivot with summarize.
73
+
74
+ Pivot data is summarized by block.
75
+
76
+ Age is summarized by block.
77
+
78
+ ```ruby
79
+ HashPivot.pivot(data, :role, :team, %w[rabbit mouse]) { |array| array.sum { |h| h[:age] } }
80
+
81
+ # [{ :role => "guest", "rabbit" => 4, "mouse" => 2 }, { :role => "admin", "rabbit" => 0, "mouse" => 4 }]
82
+ ```
83
+
84
+ role | rabbit | mouse
85
+ -- | -- | --
86
+ guest | 4 | 2
87
+ admin | 0 | 4
88
+
89
+ #### Pivot with summarize and replacing label.
90
+
91
+ If you give Hash for pivot kinds like this, pivot data is summarized by block and replace with labels.
92
+
93
+ ```ruby
94
+ pivot_kinds = { 'rabbit' => 'RABBIT AGE',
95
+ 'mouse' => 'MOUSE AGE' }
96
+ ```
97
+
98
+ ```ruby
99
+ HashPivot.pivot(data, :role, :team, pivot_kinds) { |array| array.sum { |h| h[:age] } }
100
+
101
+ # [{ :role => "guest", "RABBIT AGE" => 4, "MOUSE AGE" => 2 }, { :role => "admin", "RABBIT AGE" => 0, "MOUSE AGE" => 4 }]
102
+ ```
103
+
104
+ role | RABBIT AGE | MOUSE AGE
105
+ -- | -- | --
106
+ guest | 4 | 2
107
+ admin | 0 | 4
108
+
109
+ ### Pivot Array of Struct
110
+
111
+ #### Prepare data
112
+
113
+ Prepare Array of Struct.
114
+
115
+ ```ruby
116
+ HashPivotUserStruct = Struct.new(:id, :role, :team, :age, keyword_init: true)
117
+ data = [
118
+ HashPivotUserStruct.new(id: 1, role: 'guest', team: 'rabbit', age: 1),
119
+ HashPivotUserStruct.new(id: 2, role: 'guest', team: 'mouse', age: 2),
120
+ HashPivotUserStruct.new({ id: 3, role: 'guest', team: 'rabbit', age: 3 }),
121
+ HashPivotUserStruct.new({ id: 4, role: 'admin', team: 'mouse', age: 4 })
122
+ ]
123
+ ```
124
+
125
+ #### Basic usage
126
+
127
+ Grouping by `:role` and pivot in `:team`. Pivot column is `rabbit or mouse` .
128
+
129
+ ```ruby
130
+ HashPivot.pivot(data, :role, :team, %w[rabbit mouse], repository: HashPivot::Repository::StructRepository)
131
+
132
+ # [{ :role => "guest",
133
+ # "rabbit" => [{ :id => 1, :role => "guest", :team => "rabbit", :age => 1 }, { :id => 3, :role => "guest", :team => "rabbit", :age => 3 }],
134
+ # "mouse" => [{ :id => 2, :role => "guest", :team => "mouse", :age => 2 }] },
135
+ # { :role => "admin", "rabbit" => [], "mouse" => [{ :id => 4, :role => "admin", :team => "mouse", :age => 4 }] }]
136
+ ```
137
+
138
+
139
+ ### Pivot Array of ActiveRecord::Relation
140
+
141
+ #### Prepare data
142
+
143
+ Prepare Array of ActiveRecord::Relation.
144
+
145
+ ```ruby
146
+ class MigrateSqlDatabase < ActiveRecord::Migration[6.1]
147
+ def self.up
148
+ create_table(:hash_pivot_users) do |t|
149
+ t.string :role
150
+ t.string :team
151
+ t.integer :age
152
+ end
153
+ end
154
+ end
155
+ ```
156
+
157
+ ```ruby
158
+ HashPivotUser.destroy_all
159
+ HashPivotUser.create(:hash_pivot_user, id: 1, role: 'guest', team: 'rabbit', age: 1)
160
+ HashPivotUser.create(:hash_pivot_user, id: 2, role: 'guest', team: 'mouse', age: 2)
161
+ HashPivotUser.create(:hash_pivot_user, id: 3, role: 'guest', team: 'rabbit', age: 3)
162
+ HashPivotUser.create(:hash_pivot_user, id: 4, role: 'admin', team: 'mouse', age: 4)
163
+ ```
164
+
165
+ #### Basic usage
166
+
167
+ Grouping by `:role` and pivot in `:team`. Pivot column is `rabbit or mouse` .
168
+
169
+ ```ruby
170
+ HashPivot.pivot(data, :role, :team, %w[rabbit mouse], repository: HashPivot::Repository::ActiveRecordRepository)
171
+
172
+ # [{ :role => "guest",
173
+ # "rabbit" => [{ :id => 1, :role => "guest", :team => "rabbit", :age => 1 }, { :id => 3, :role => "guest", :team => "rabbit", :age => 3 }],
174
+ # "mouse" => [{ :id => 2, :role => "guest", :team => "mouse", :age => 2 }] },
175
+ # { :role => "admin", "rabbit" => [], "mouse" => [{ :id => 4, :role => "admin", :team => "mouse", :age => 4 }] }]
176
+ ```
177
+
22
178
 
23
179
  ## Development
24
180
 
data/hash_pivot.gemspec CHANGED
@@ -16,7 +16,8 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.metadata['homepage_uri'] = spec.homepage
18
18
  spec.metadata['source_code_uri'] = spec.homepage
19
- spec.metadata['changelog_uri'] = "#{spec.homepage}CHANGELOG.md"
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
+ spec.metadata['documentation_uri'] = 'https://rubydoc.info/gems/hash_pivot'
20
21
 
21
22
  # Specify which files should be added to the gem when it is released.
22
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -6,34 +6,51 @@ require_relative './repository/struct_repository'
6
6
 
7
7
  module HashPivot
8
8
  class Table
9
+ # rubocop:disable Layout/LineLength
10
+
9
11
  # @param [Array<Hash>] data
12
+ # @param [Class<HashPivot::Repository::HashRepository,HashPivot::Repository::StructRepository,HashPivot::Repository::ActiveRecordRepository>] repository
10
13
  def initialize(data, repository: HashPivot::Repository::HashRepository)
11
14
  @data = data
12
15
  @repository = repository
13
16
  end
14
17
 
18
+ # rubocop:enable Layout/LineLength
19
+
15
20
  # @param [Array, Object] group
16
21
  # @param [Object] pivot_in
17
- # @param [Array] pivot_kinds
22
+ # @param [Hash,nil] pivot_kinds
23
+ # @param [Proc] block
24
+ # @return [Array<Hash>]
18
25
  def pivot(group, pivot_in, pivot_kinds, &block)
19
26
  group = [group] unless group.is_a?(Array)
20
27
  @repository.hash_by_group(@data, group, pivot_in).each_with_object([]) do |(key, array), memo|
21
- hash = pivot_with_sum(pivot_kinds, array, pivot_in, &block)
28
+ hash = transpose_with(pivot_kinds, array, pivot_in, &block)
22
29
 
23
30
  memo << key.merge(hash)
24
31
  end
25
32
  end
26
33
 
27
- def pivot_with_sum(pivot_kinds, array, pivot_in, &block)
28
- pivot_kinds ||= array.map { |h| h[pivot_in] }.uniq.compact
29
- pivot_kinds.each_with_object({}) do |pivot_kind, memo|
34
+ private
35
+
36
+ # @param [Hash,nil] pivot_kinds
37
+ # @param [Array] array
38
+ # @param [Object] pivot_in
39
+ # @param [Proc] block
40
+ # @return [Hash]
41
+ def transpose_with(pivot_kinds, array, pivot_in, &block)
42
+ pivot_kinds ||= calculated_pivot_kinds_from(array, pivot_in)
43
+ pivot_kinds.each_with_object({}) do |(pivot_kind, pivot_label), memo|
30
44
  pivoted_data = array.select { |h| h[pivot_in] == pivot_kind }
31
- memo[pivot_kind] = if block
32
- yield(pivoted_data)
33
- else
34
- pivoted_data
35
- end
45
+ memo[pivot_label] = block ? yield(pivoted_data) : pivoted_data
36
46
  end
37
47
  end
48
+
49
+ # @param [Array] array
50
+ # @param [Object] pivot_in
51
+ # @return [Hash]
52
+ def calculated_pivot_kinds_from(array, pivot_in)
53
+ array.map { |h| h[pivot_in] }.uniq.compact.each_with_object({}) { |kind, memo| memo[kind] = kind }
54
+ end
38
55
  end
39
56
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HashPivot
4
- VERSION = '0.1.0'
4
+ VERSION = '0.3.1'
5
5
  end
data/lib/hash_pivot.rb CHANGED
@@ -4,12 +4,28 @@ require_relative 'hash_pivot/version'
4
4
  require_relative 'hash_pivot/table'
5
5
  require 'hash_pivot/error/not_implemented_error'
6
6
  module HashPivot
7
+ # rubocop:disable Layout/LineLength
8
+
7
9
  # @param [Array<Hash>] data
8
10
  # @param [Array] group
9
11
  # @param [Object] pivot_in
10
- # @param [Array] pivot_kinds
12
+ # @param [Array,Hash,nil] pivot_header
11
13
  # @return [Hash]
12
- def self.pivot(data, group, pivot_in, pivot_kinds, repository: HashPivot::Repository::HashRepository, &block)
14
+ # @param [Class<HashPivot::Repository::HashRepository,HashPivot::Repository::StructRepository,HashPivot::Repository::ActiveRecordRepository>] repository
15
+ # @param [Proc] block
16
+ def self.pivot(data, group, pivot_in, pivot_header, repository: HashPivot::Repository::HashRepository, &block)
17
+ pivot_kinds = if pivot_header.is_a?(Array)
18
+ transform_to_hash(pivot_header)
19
+ else
20
+ pivot_header
21
+ end
13
22
  Table.new(data, repository: repository).pivot(group, pivot_in, pivot_kinds, &block)
14
23
  end
24
+
25
+ # rubocop:enable Layout/LineLength
26
+
27
+ def self.transform_to_hash(array)
28
+ array.each_with_object({}) { |kind, memo| memo[kind] = kind }
29
+ end
30
+ private_class_method :transform_to_hash
15
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hash_pivot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - junara
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-26 00:00:00.000000000 Z
11
+ date: 2022-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -182,7 +182,8 @@ licenses:
182
182
  metadata:
183
183
  homepage_uri: https://github.com/junara/hash_pivot
184
184
  source_code_uri: https://github.com/junara/hash_pivot
185
- changelog_uri: https://github.com/junara/hash_pivotCHANGELOG.md
185
+ changelog_uri: https://github.com/junara/hash_pivot/blob/main/CHANGELOG.md
186
+ documentation_uri: https://rubydoc.info/gems/hash_pivot
186
187
  rubygems_mfa_required: 'true'
187
188
  post_install_message:
188
189
  rdoc_options: []