hash_extend 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,2 +1,265 @@
1
- hash_extend
2
- ===========
1
+ # HashExtend
2
+
3
+ Extend ruby Hash. No override.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'hash_extend'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install hash_extend
18
+
19
+ ## Usage
20
+
21
+ ### stealth_delete
22
+
23
+ Delete key(s) passed by, but return the hash instead of the deleted value
24
+
25
+ ```ruby
26
+ stealth_delete! *keys
27
+ stealth_delete *keys
28
+ ```
29
+
30
+ Demo
31
+
32
+ ```ruby
33
+ {:one=>1, :two=>2, :three=>3}.stealth_delete :one
34
+ #=> {:two=>2, :three=>3}
35
+
36
+ {:one=>1, :two=>2, :three=>3}.stealth_delete :one, :three
37
+ #=> {:two=>2}
38
+
39
+ {:one=>1, :two=>2, :three=>3}.stealth_delete :four
40
+ #=> {:one=>1, :two=>2, :three=>3}
41
+
42
+ {:one=>1, :two=>2, :three=>3}.stealth_delete :one, :four
43
+ #=> {:two=>2, :three=>3}
44
+ ```
45
+
46
+ Code
47
+
48
+ ```ruby
49
+ def stealth_delete! *keys
50
+ keys.each do |key|
51
+ delete key
52
+ end
53
+ return self
54
+ end
55
+ ```
56
+
57
+
58
+ ### map_values
59
+
60
+ Update values through block
61
+
62
+ ```ruby
63
+ map_values!
64
+ map_values
65
+ ```
66
+
67
+ Demo
68
+
69
+ ```ruby
70
+ # square values
71
+ {:one=>1, :two=>2, :three=>3}.map_values{ |value| value ** 2 }
72
+ #=> {:one=>1, :two=>4, :three=>9}
73
+ ```
74
+
75
+ Code
76
+
77
+ ```ruby
78
+ def map_values!
79
+ self.each do |key, value|
80
+ self[key] = yield value
81
+ end
82
+ end
83
+ ```
84
+
85
+
86
+ ### map_keys
87
+
88
+ Update keys through block
89
+
90
+ ```ruby
91
+ map_keys!
92
+ map_keys
93
+ ```
94
+
95
+ Demo
96
+
97
+ ```ruby
98
+ {"one"=>1, "two"=>2, "three"=>3}.map_keys(&:to_sym)
99
+ #=> {:one=>1, :two=>2, :three=>3}
100
+ ```
101
+
102
+ Code
103
+
104
+ ```ruby
105
+ def map_keys
106
+ self.inject({}) do |hash, (key, value)|
107
+ hash[yield key] = value; hash
108
+ end
109
+ end
110
+
111
+ def map_keys! &block
112
+ to_map = self.dup
113
+ self.clear.merge! to_map.map_keys &block
114
+ end
115
+ ```
116
+
117
+ Perfomances : Generaly, use the "!" is faster than the "no self modification" methods. Cause the last one used to "dup" the object. As we can't modify keys hash during iteration, here it's the reverse.
118
+
119
+
120
+ ### delete_many
121
+
122
+ Delete severals keys in one
123
+
124
+ Demo
125
+
126
+ ```ruby
127
+ h = Hash[:one, 1, :two, 2, :three, 3] #=> {:one=>1, :two=>2, :three=>3}
128
+ h.delete_many(:un, :trois) #=> [1, 3]
129
+ h #=> {:two=>2}
130
+
131
+ h.delete_many(:six) #=> [nil]
132
+ ```
133
+
134
+ Code
135
+
136
+ ```ruby
137
+ def delete_many *keys
138
+ keys.map{ |key| self.delete(key) }
139
+ end
140
+ ```
141
+
142
+
143
+ ### insert
144
+
145
+ Insert a value through descendance of keys (hash in hash)
146
+
147
+ Demo
148
+
149
+ ```ruby
150
+ h = Hash.new #=> {}
151
+ h.insert(12, :calendar, :gregorian, :months)
152
+ #=> {:calendar => {:gregorian => {:months => 12}}}
153
+
154
+ h.insert(13, :calendar, :lunar, :months)
155
+ #=> {:calendar => {:gregorian => {:months => 12}, :lunar => {:months => 13}}}
156
+ ```
157
+
158
+ Code
159
+
160
+ ```ruby
161
+ def insert value, *keys
162
+ if keys.size > 1
163
+ shifted = keys.shift
164
+
165
+ self[shifted] ||= Hash.new
166
+ self[shifted] = self[shifted].insert value, *keys
167
+ else
168
+ self[keys.first] = value
169
+ end
170
+
171
+ self
172
+ end
173
+ ```
174
+
175
+
176
+ ### compact
177
+
178
+ Allow to compact hash just like arrays. Well, you can check nil, or black, or whatever you want on keys OR values
179
+
180
+ ```ruby
181
+ compact! options = Hash.new
182
+ compact options = Hash.new
183
+ ```
184
+
185
+ Arguments : ':compare' must be in %w{key value}, default is :value
186
+ Arguments : ':with' is recommended in %w{blank? empty?}, default is :nil?
187
+
188
+ Demo
189
+
190
+ ```ruby
191
+ {:un=>1, :deux=>2, :trois=>3, :quatre=>nil, :cinq=>[]}.compact!
192
+ #=> {:cinq=>[], :un=>1, :deux=>2, :trois=>3}
193
+
194
+ {:un=>1, :deux=>2, :trois=>3, :quatre=>nil, :cinq=>[]}.compact!(:with=>:blank?)
195
+ #=> {:un=>1, :deux=>2, :trois=>3}
196
+
197
+ # for the perverts ones
198
+ {:un=>1, :deux=>2, :trois=>3, :quatre=>nil, :cinq=>[]}.compact!(:with=>"is_a?(Fixnum)")
199
+ #=> {:quatre=>nil, :cinq=>[]}
200
+
201
+ # And for the ones who REALLY care about memory
202
+ {:un=>1, "deux"=>2, "trois"=>3, "quatre"=>nil, :cinq=>[]}.compact!(:compare => :key, :with=>"is_a?(String)")
203
+ #=> {:un=>1, :cinq=>[]}
204
+ ```
205
+
206
+ Code
207
+
208
+ ```ruby
209
+ def compact! options = Hash.new
210
+ compare = options.delete(:compare) || :value
211
+ raise ArgumentError, ":compare option must be in %w{key value}" unless [:key, :value].include? compare.to_sym
212
+
213
+ if (with = options.delete :with)
214
+ self.each do |key, value|
215
+ self.delete(key) if eval "#{ compare }.#{ with }"
216
+ end
217
+
218
+ else
219
+ self.each do |key, value|
220
+ self.delete(key) if eval "#{ compare }.nil?"
221
+ end
222
+ end
223
+
224
+ self
225
+ end
226
+ ```
227
+
228
+
229
+ ### select_by
230
+
231
+ Select into hash from a collection of keys. Usefull to select correct params after a form.
232
+
233
+ ```ruby
234
+ select_by! *collection
235
+ select_by *collection
236
+ ```
237
+
238
+ Demo
239
+
240
+ ```ruby
241
+ {:one=>1, :two=>2, :three=>3, :four=>4}.select_by :one, :three
242
+ #=> {:one=>1, :three=>3}
243
+
244
+ {:one=>1, :two=>2, :three=>3, :four=>4}.select_by :one, :six
245
+ #=> {:one=>1}
246
+
247
+ {:one=>1, :two=>2, :three=>3, :four=>4}.select_by :six, :seven
248
+ #=> {}
249
+ ```
250
+
251
+ Code
252
+
253
+ ```ruby
254
+ def select_by! *collection
255
+ self.keep_if{ |field, _| collection.include? field.to_sym }
256
+ end
257
+ ```
258
+
259
+ ## Contributing
260
+
261
+ 1. Fork it
262
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
263
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
264
+ 4. Push to the branch (`git push origin my-new-feature`)
265
+ 5. Create new Pull Request
@@ -1,3 +1,3 @@
1
1
  module HashExtend
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/hash_extend.rb CHANGED
@@ -1,19 +1,114 @@
1
1
  require "hash_extend/version"
2
2
 
3
3
  class Hash
4
+
5
+ # ?> {1=>1, 2=>2}.stealth_delete(1)
6
+ # => {2=>2}
7
+ # delete key(s) but return self instead of deleted value
8
+ def stealth_delete! *keys
9
+ keys.each do |key|
10
+ delete key
11
+ end
12
+ return self
13
+ end
14
+
15
+
16
+ # ?> {1=>1, 2=>2}.map_values{ |v| v**2 }
17
+ # => {1=>1, 2=>4}
18
+ # modify values fro hash through block
19
+ def map_values!
20
+ self.each do |key, value|
21
+ self[key] = yield value
22
+ end
23
+ end
24
+
25
+ # ?> {1=>1, 2=>2}.map_keys{ |k| k.to_s }
26
+ # => {"2"=>2, "1"=>1}
27
+ # modify keys from hash through block
28
+ def map_keys
29
+ self.inject({}) do |hash, (key, value)|
30
+ hash[yield key] = value; hash
31
+ end
32
+ end
33
+
34
+ def map_keys! &block
35
+ to_map = self.dup
36
+ self.clear.merge! to_map.map_keys &block
37
+ end
38
+
39
+
40
+ # ?> h = Hash[:un, 1, :deux, 2, :trois, 3]
41
+ # => {:un=>1, :deux=>2, :trois=>3}
42
+ # ?> h.delete_many(:un, :trois)
43
+ # => [1, 3]
44
+ # ?> h
45
+ # => {:deux=>2}
46
+ #
47
+ # ?> h.delete_many(:six)
48
+ # => [nil]
49
+ # delete severals keys in one time
4
50
  def delete_many *keys
5
51
  keys.map{ |key| self.delete(key) }
6
52
  end
7
-
8
- def select_from_collection! collection
9
- self.keep_if{ |field, value| collection.include? field.to_sym }
53
+
54
+
55
+ # ?> insert("valeur", Hash.new, :key_one, :key_two, :key_wi)
56
+ # => {:key_one=>{:key_two=>{:key_wi=>"valeur"}}}
57
+ # insert a value trough severals "levels" of hashs
58
+ def insert value, *keys
59
+ if keys.size > 1
60
+ shifted = keys.shift
61
+
62
+ self[shifted] ||= Hash.new
63
+ self[shifted] = self[shifted].insert value, *keys
64
+ else
65
+ self[keys.first] = value
66
+ end
67
+
68
+ self
10
69
  end
11
-
12
- ["select_from_collection"].each do |method_name|
13
- define_method method_name do |*args|
70
+
71
+ # ?> {:un=>1, :deux=>2, :trois=>3, :quatre=>nil, :cinq=>[]}.compact!
72
+ # => {:cinq=>[], :un=>1, :deux=>2, :trois=>3}
73
+ # ?> {:un=>1, :deux=>2, :trois=>3, :quatre=>nil, :cinq=>[]}.compact!(:with=>:blank?)
74
+ # => {:un=>1, :deux=>2, :trois=>3}
75
+ # ?> {:un=>1, :deux=>2, :trois=>3, :quatre=>nil, :cinq=>[]}.compact!(:with=>"is_a?(Fixnum)")
76
+ # => {:quatre=>nil, :cinq=>[]}
77
+ # allow to compact (like Array), default on value.nil?
78
+ def compact! options = Hash.new
79
+ compare = options.delete(:compare) || :value
80
+ raise ArgumentError, ":compare option must be in %w{key value}" unless [:key, :value].include? compare.to_sym
81
+
82
+ if (with = options.delete :with)
83
+ self.each do |key, value|
84
+ self.delete(key) if eval "#{ compare }.#{ with }"
85
+ end
86
+
87
+ else
88
+ self.each do |key, value|
89
+ self.delete(key) if eval "#{ compare }.nil?"
90
+ end
91
+ end
92
+
93
+ self
94
+ end
95
+
96
+
97
+ # ?> {:action=>"index", :controller=>"home", :id=>"42", :firstname=>"thomas", :name=>"petrachi"}.select_from_collection! [:id, :firstname, :name]
98
+ # => {:firstname=>"thomas", :name=>"petrachi", :id=>"42"}
99
+ # something like #keep_if, but instead of block, pass collection of keys to select
100
+ def select_by! collection, *args, &block
101
+ self.keep_if{ |field, _| collection.include? field.to_sym }
102
+ end
103
+
104
+
105
+ # duplicate method without self modification
106
+ [:stealth_delete, :map_values, :compact, :select_by].each do |method_name|
107
+ define_method method_name do |*args, &block|
14
108
  hash = self.dup
15
- eval "hash.#{ method_name }! *args"
109
+ eval "hash.#{ method_name }! *args, &block"
16
110
  return hash
17
111
  end
18
112
  end
113
+
19
114
  end
metadata CHANGED
@@ -1,33 +1,23 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hash_extend
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Thomas Petrachi
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-09-27 00:00:00 Z
12
+ date: 2012-09-30 00:00:00.000000000 Z
19
13
  dependencies: []
20
-
21
- description: "in dev : extend hash methods"
22
- email:
14
+ description: ! 'in dev : extend hash methods'
15
+ email:
23
16
  - thomas.petrachi@vodeclic.com
24
17
  executables: []
25
-
26
18
  extensions: []
27
-
28
19
  extra_rdoc_files: []
29
-
30
- files:
20
+ files:
31
21
  - .gitignore
32
22
  - Gemfile
33
23
  - LICENSE.txt
@@ -36,38 +26,28 @@ files:
36
26
  - hash_extend.gemspec
37
27
  - lib/hash_extend.rb
38
28
  - lib/hash_extend/version.rb
39
- homepage: ""
29
+ homepage: ''
40
30
  licenses: []
41
-
42
31
  post_install_message:
43
32
  rdoc_options: []
44
-
45
- require_paths:
33
+ require_paths:
46
34
  - lib
47
- required_ruby_version: !ruby/object:Gem::Requirement
35
+ required_ruby_version: !ruby/object:Gem::Requirement
48
36
  none: false
49
- requirements:
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- hash: 3
53
- segments:
54
- - 0
55
- version: "0"
56
- required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
42
  none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
65
47
  requirements: []
66
-
67
48
  rubyforge_project:
68
49
  rubygems_version: 1.8.24
69
50
  signing_key:
70
51
  specification_version: 3
71
- summary: "in dev : add :delete_many"
52
+ summary: ! 'in dev : add :delete_many'
72
53
  test_files: []
73
-