This gem is no longer maintained.
Extend ruby Hash. No override.
Validate for Ruby 1.9.3 and Ruby ree-1.8.7
Add this line to your application's Gemfile:
gem 'hash_extend'
And then execute:
$ bundle
Or install it yourself as:
$ gem install hash_extend
method 'stealth_delete' is deprecated and will be deleted in version 2.4 - Use 'except' to fit Rails's ActiveSupport
--
Delete key(s) passed by, but return the hash instead of the deleted value
stealth_delete! *keys
stealth_delete *keys
Demo
{:one=>1, :two=>2, :three=>3}.stealth_delete :one
#=> {:two=>2, :three=>3}
{:one=>1, :two=>2, :three=>3}.stealth_delete :one, :three
#=> {:two=>2}
{:one=>1, :two=>2, :three=>3}.stealth_delete :four
#=> {:one=>1, :two=>2, :three=>3}
{:one=>1, :two=>2, :three=>3}.stealth_delete :one, :four
#=> {:two=>2, :three=>3}
Code
def stealth_delete! *keys
keys.each do |key|
delete key
end
return self
end
Update values through block
map_values!
map_values
Demo
# square values
{:one=>1, :two=>2, :three=>3}.map_values{ |value| value ** 2 }
#=> {:one=>1, :two=>4, :three=>9}
Code
def map_values!
self.each do |key, value|
self[key] = yield value
end
end
Update keys through block
map_keys!
map_keys
Demo
{"one"=>1, "two"=>2, "three"=>3}.map_keys(&:to_sym)
#=> {:one=>1, :two=>2, :three=>3}
Code
def map_keys
self.inject({}) do |hash, (key, value)|
hash[yield key] = value; hash
end
end
def map_keys! &block
to_map = self.dup
self.clear.merge! to_map.map_keys &block
end
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.
Delete severals keys in one
Demo
h = Hash[:one, 1, :two, 2, :three, 3] #=> {:one=>1, :two=>2, :three=>3}
h.delete_many(:one, :three) #=> [1, 3]
h #=> {:two=>2}
h.delete_many(:six) #=> [nil]
Code
def delete_many *keys
keys.map{ |key| self.delete(key) }
end
--
FYI : ActiveSupport provide method 'slice'.
h = Hash[:one, 1, :two, 2, :three, 3] #=> {:one=>1, :two=>2, :three=>3}
h.slice(:one, :three) #=> {:three=>3, :one=>1}
h #=> {:one=>1, :two=>2, :three=>3}
h.slice(:six) #=> {}
WARNING : slice! has not the same behavior. Check out ActiveSupport guides for more information : http://guides.rubyonrails.org/active_support_core_extensions.html
--
FYI : Rails 3's ActiveSupport provide method 'extract!'. (this gem provide method 'extract!' for Rails < 3)
h = Hash[:one, 1, :two, 2, :three, 3] #=> {:one=>1, :two=>2, :three=>3}
h.extract!(:one, :three) #=> {:one=>1, :three=>3}
h #=> {:two=>2}
h.extract!(:six) #=> {:six=>nil}
Insert a value through descendance of keys (hash in hash)
Demo
h = Hash.new #=> {}
h.insert(12, :calendar, :gregorian, :months)
#=> {:calendar => {:gregorian => {:months => 12}}}
h.insert(13, :calendar, :lunar, :months)
#=> {:calendar => {:gregorian => {:months => 12}, :lunar => {:months => 13}}}
Code
def insert value, *keys
if keys.size > 1
shifted = keys.shift
self[shifted] ||= Hash.new
self[shifted] = self[shifted].insert value, *keys
else
self[keys.first] = value
end
self
end
Allow to compact hash just like arrays. Well, you can check nil, or black, or whatever you want on keys OR values
compact! options = Hash.new
compact options = Hash.new
Arguments : ':compare' must be in %w{key value}, default is :value Arguments : ':with' is recommended in %w{blank? empty?}, default is :nil?
Demo
{:one=>1, :two=>2, :three=>3, :four=>nil, :five=>[]}.compact!
#=> {:five=>[], :one=>1, :two=>2, :three=>3}
{:one=>1, :two=>2, :three=>3, :four=>nil, :five=>[]}.compact!(:with=>:blank?)
#=> {:one=>1, :two=>2, :three=>3}
# for the perverts ones
{:one=>1, :two=>2, :three=>3, :four=>nil, :five=>[]}.compact!(:with=>"is_a?(Fixnum)")
#=> {:four=>nil, :five=>[]}
# And for the ones who REALLY care about memory
{:one=>1, "two"=>2, "three"=>3, "four"=>nil, :five=>[]}.compact!(:compare => :key, :with=>"is_a?(String)")
#=> {:one=>1, :five=>[]}
Code
def compact! options = Hash.new
compare = options.delete(:compare) || :value
raise ArgumentError, ":compare option must be in %w{key value}" unless [:key, :value].include? compare.to_sym
if (with = options.delete :with)
self.each do |key, value|
self.delete(key) if eval "#{ compare }.#{ with }"
end
else
self.each do |key, value|
self.delete(key) if eval "#{ compare }.nil?"
end
end
self
end
method 'select_by' is deprecated and will be deleted in version 2.4 - Use 'slice' to fit Rails's ActiveSupport
method 'select_by!' is deprecated and will be deleted in version 2.4 - Use 'extract!' to fit Rails's ActiveSupport
--
Select into hash from a collection of keys. Usefull to select correct params after a form.
select_by! *keys
select_by *keys
Demo
{:one=>1, :two=>2, :three=>3, :four=>4}.select_by :one, :three
#=> {:one=>1, :three=>3}
{:one=>1, :two=>2, :three=>3, :four=>4}.select_by :one, :six
#=> {:one=>1}
{:one=>1, :two=>2, :three=>3, :four=>4}.select_by :six, :seven
#=> {}
Code
def select_by! *keys
self.delete_if{ |field, _| !keys.include? field.to_sym }
end
Select into hash from a collection of keys
extract! *keys
Demo
h = Hash[:one, 1, :two, 2, :three, 3] #=> {:two=>2, :three=>3, :one=>1}
h.extract! :one, :three #=> {:one=>1, :three=>3}
h #=> {:two=>2}
{:one=>1, :two=>2, :three=>3, :four=>4}.extract! :one, :six
#=> {:one=>1, :six=>nil}
{:one=>1, :two=>2, :three=>3, :four=>4}.extract! :six, :seven
#=> {:six=>nil, :seven=>nil}
Code
def extract! *keys
hash = {}
keys.each {|key| hash[key] = delete(key) }
hash
end
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request