hash_pivot 0.1.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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: []