Dudo
Dudo

Reputation: 4169

ruby hash as first element of array

I'm parsing JSON from an API. I have a foo element that's a hash sometimes, and an array of hashes, other times.

foo: { ... }

foo: [
  { ... },
  { ... }
]

I'd like to just use Array(foo) to always get the an array with at least the one element, but it converts the hash to [[..., ...], [..., ...]]. Is there an elegant way to handle this, besides using foo.is_a?(Hash/Array)?

Upvotes: 1

Views: 217

Answers (3)

Veets
Veets

Reputation: 171

If you want to solve it using plain Ruby then you can push the item(s) (either Array of Hashes or Hash) to an empty array and then flatten the array like following:

2.0.0-p247 :001 > [{a:1}].flatten(1)
 => [{:a=>1}] 
2.0.0-p247 :002 > [[{a:1},{b:2}]].flatten(1)
 => [{:a=>1}, {:b=>2}]

i.e. [foo].flatten(1) should work.

Upvotes: 2

yez
yez

Reputation: 2378

In a Rails environment, with access to activesupport:

You could use Array.wrap

foo = { a: :b }
=> {:a=>:b}
Array.wrap(foo)
=> [{:a=>:b}]
Array.wrap([1,2,3])
=> [1, 2, 3]

Without Rails, you could do gem install activesupport and then in your code: require 'activesupport'

Upvotes: 3

Harsh Gupta
Harsh Gupta

Reputation: 4538

Adding to @yez answer, if you are not using activesupport, you can extend Array to have a wrap function:

def Array.wrap(object)
  if object.nil?
    []
  elsif object.respond_to?(:to_ary)
    object.to_ary || [object]
  else
    [object]
  end
end

Copied from http://apidock.com/rails/Array/wrap/class

Another crude way to implement it is:

def Array.wrap(object)
  return [] if object.nil?
  [object].flatten(1)
end

Upvotes: 3

Related Questions