Skip to content

Instantly share code, notes, and snippets.

@pdougall1
Last active September 21, 2017 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdougall1/dac0945584ee3f3a34c476fed6f50a3a to your computer and use it in GitHub Desktop.
Save pdougall1/dac0945584ee3f3a34c476fed6f50a3a to your computer and use it in GitHub Desktop.
class Hash
def deep_clone
Marshal.load(Marshal.dump(self))
end
def compact
self.select { |_, value| !value.nil? }
end
def deep_compact(opts={})
self.inject({}) do |new_hash, (k,v)|
if !v.nil?
new_hash[k] = opts[:recurse] && v.class == Hash ? v.compact(opts) : v
end
new_hash
end
end
def deep_camelize_keys
deep_transform_keys { |k| _camelize(k, false) }
end
def deep_underscore_keys
deep_transform_keys { |k| _underscore(k) }
end
def deep_symbolize_keys
deep_transform_keys { |k| k.to_sym }
end
def deep_stringify_keys
deep_transform_keys { |k| k.to_s }
end
def deep_transform_keys(&block)
_deep_transform_keys_in_object(self, &block)
end
def deep_transform_values(&block)
_deep_transform_values_in_object(self, &block)
end
private
def _camelize(string, uppercase_first_letter = true)
string = string.to_s
if uppercase_first_letter
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
else
string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
end
string = string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
string
end
def _underscore(string)
is_sym = string.is_a?(Symbol)
string = string
.to_s
.gsub(/::/, '/')
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
.tr("-", "_")
.downcase
string = string.to_sym if is_sym
return string
end
def _deep_transform_keys_in_object(object, &block)
if object.respond_to? :keys
object.each_with_object({}) do |(key, value), result|
result[yield(key)] = _deep_transform_keys_in_object(value, &block)
end
elsif object.respond_to? :each
object.map {|e| _deep_transform_keys_in_object(e, &block) }
else
object
end
end
def _deep_transform_values_in_object(object, &block)
if object.respond_to? :keys
object.each_with_object({}) do |(key, value), result|
result[key] = _deep_transform_values_in_object(value, &block)
end
elsif object.respond_to? :each
object.map {|e| _deep_transform_keys_in_object(e, &block) }
else
yield(object)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment