Skip to content

Instantly share code, notes, and snippets.

@damien
Last active August 29, 2015 14:23
Show Gist options
  • Save damien/8c1b40afe020786c9ad2 to your computer and use it in GitHub Desktop.
Save damien/8c1b40afe020786c9ad2 to your computer and use it in GitHub Desktop.
Utilities for performing recursive operations on an object
module Recurse
# Iterate over obj and all of it's values, copying them into a flat array
# @return [Array]
# @example Flattening a nested hash
# { foo: { bar: { fizz: 'buzz' } } }.flatten_recursively
# # => [:foo, :bar, :fizz, "buzz"]
#
# @example Flattening an array of mixed objects
# [{ fizz: :buzz }, { foo: :bar }, [1, [2, 3]]].flatten_recursively
# # => [:fizz, :buzz, :foo, :bar, 1, 2, 3]
def flatten_recursively
if self.is_a?(Hash)
self.map do |key, value|
[key] + value.flatten_recursively
end.flatten
elsif self.is_a?(Array)
self.map { |value| value.flatten_recursively }.flatten
else
[self]
end
end
# Freze an object. If it is a hash or an array, recursively enumerate
# over all of it and it's children's values and freeze them as well.
# @return [Object]
# @example Freezing values in a nested hash
# hash = { foo: { bar: { fizz: 'buzz' } } }.freeze
# hash[:foo][:bar][:fizz].frozen?
# # => false
#
# hash = { foo: { bar: { fizz: 'buzz' } } }.freeze_recursively!
# hash[:foo][:bar][:fizz].frozen?
# # => true
def freeze_recursively!
if self.is_a?(Hash)
self.each do |key, value|
value.freeze_recursively!
end
elsif self.is_a?(Array)
self.each { |value| value.freeze_recursively! }
else
self.freeze
end
self
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment