Created
March 12, 2014 15:30
-
-
Save cbartlett/9509258 to your computer and use it in GitHub Desktop.
Hash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/core_ext/hash.rb | |
module CoreExt | |
module Hash | |
def deep_fetch(*keys, &default) | |
keys.inject(self) do |hsh, key| | |
hsh.fetch(key, &(proc { |*args| return default.call(*args) } if default)) | |
end | |
end | |
end | |
end | |
Hash.class_eval do | |
include CoreExt::Hash | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/hash_patches.rb | |
class Hash | |
def except_blank! | |
# Remove empty values | |
values.each{|h| h.except_blank! if h.is_a?(Hash)} | |
# Remove empty inside array | |
values.select{|v| v.is_a?(Array)}.flatten.each{|h| h.except_blank! if h.is_a?(Hash)} | |
# Booleans are allowed | |
delete_if { |k, v| v.blank? and not !!v == v } | |
self | |
end | |
def except_blank | |
self.dup.except_blank! | |
end | |
def widdle(*symbols) | |
result = self | |
symbols.each { |s| result = result[s] rescue nil } | |
result | |
end | |
def symbolize_all_keys! | |
symbolize_keys! | |
# Symbolize each hash in values | |
values.each{|h| h.symbolize_all_keys! if h.is_a?(Hash)} | |
# Symbolize each hash inside array | |
values.select{|v| v.is_a?(Array)}.flatten.each{|h| h.symbolize_all_keys! if h.is_a?(Hash)} | |
self | |
end | |
def symbolize_all_keys | |
self.dup.symbolize_all_keys! | |
end | |
def stringify_all_keys! | |
stringify_keys! | |
# Symbolize each hash in values | |
values.each{|h| h.stringify_all_keys! if h.is_a?(Hash)} | |
# Symbolize each hash inside array | |
values.select{|v| v.is_a?(Array)}.flatten.each{|h| h.stringify_all_keys! if h.is_a?(Hash)} | |
self | |
end | |
def stringify_all_keys | |
self.dup.stringify_all_keys! | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/hash.rb | |
require 'core_ext/hash' | |
Hash.class_eval do | |
def delete_blank | |
delete_if do |k, v| | |
(v.respond_to?(:empty?) ? v.empty? : !v) or (v.instance_of?(Hash) || v.instance_of?(BSON::OrderedHash)) && v.delete_blank.empty? | |
end | |
end | |
def recursive_symbolize_keys! | |
symbolize_keys! | |
# symbolize each hash in .values | |
values.each{|h| h.recursive_symbolize_keys! if h.is_a?(Hash) } | |
# symbolize each hash inside an array in .values | |
values.select{|v| v.is_a?(Array) }.flatten.each{|h| h.recursive_symbolize_keys! if h.is_a?(Hash) } | |
self | |
end | |
def recursive_symbolize_keys | |
self.dup.recursive_symbolize_keys! | |
end | |
# | |
# Recursive version of Hash#merge! | |
# | |
# Adds the contents of +other_hash+ to +hsh+, | |
# merging entries in +hsh+ with duplicate keys with those from +other_hash+. | |
# | |
# Compared with Hash#merge!, this method supports nested hashes. | |
# When both +hsh+ and +other_hash+ contains an entry with the same key, | |
# it merges and returns the values from both arrays. | |
# | |
# h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}} | |
# h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}} | |
# h1.rmerge!(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}} | |
# | |
# Simply using Hash#merge! would return | |
# | |
# h1.merge!(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}} | |
# | |
def rmerge!(other_hash) | |
merge!(other_hash) do |key, oldval, newval| | |
oldval.class == self.class ? oldval.rmerge!(newval) : newval | |
end | |
end | |
# | |
# Recursive version of Hash#merge | |
# | |
# Compared with Hash#merge!, this method supports nested hashes. | |
# When both +hsh+ and +other_hash+ contains an entry with the same key, | |
# it merges and returns the values from both arrays. | |
# | |
# Compared with Hash#merge, this method provides a different approch | |
# for merging nasted hashes. | |
# If the value of a given key is an Hash and both +other_hash+ abd +hsh | |
# includes the same key, the value is merged instead replaced with | |
# +other_hash+ value. | |
# | |
# h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}} | |
# h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}} | |
# h1.rmerge(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}} | |
# | |
# Simply using Hash#merge would return | |
# | |
# h1.merge(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}} | |
# | |
def rmerge(other_hash) | |
r = {} | |
merge(other_hash) do |key, oldval, newval| | |
r[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment