Jwan622 Jwan622 - 5 months ago 6
Ruby Question

Calling flatten on a hash in ruby. Oddities

Say I have the following hash:

error_hash = {
:base => [
[0] [
[0] "Address is required to activate"
]
]
}


Are these results odd?

[18] pry(#<Api::UsersController>)> error_hash.flatten
[
[0] :base,
[1] [
[0] [
[0] "Address is required to activate"
]
]
]
[19] pry(#<Api::UsersController>)> error_hash.flatten(1)
[
[0] :base,
[1] [
[0] [
[0] "Address is required to activate"
]
]
]
[20] pry(#<Api::UsersController>)> error_hash.flatten(2)
[
[0] :base,
[1] [
[0] "Address is required to activate"
]
]
[21] pry(#<Api::UsersController>)> error_hash.flatten(3)
[
[0] :base,
[1] "Address is required to activate"
]


I would have expected
.flatten
to have been equal to
flatten(3)
, or in otherwords, I would have expected
.flatten
to have flattened recursively until evereything was in a single array.

Answer

Why would you expect flatten to act recursively when the documentation does suggest otherwise?

You can extend the capability of hash using following:

class Hash
  def flatten_deepest
    self.each_with_object({}) do |(key, val), h|
      if val.is_a? Hash
        val.flatten_to_root.map do |hash_key, hash_val|
          h["#{key}.#{hash_key}".to_sym] = hash_val
        end
      else
        h[k] = val
      end
    end
  end
end

and then do:

 error_hash.flatten_deepest

I think you got the idea.