Katya
Katya

Reputation: 138

Sort arrays and hashes

I have bunch of data:

[{"id"=>"3"}, {"id"=>"9"}]
{"id"=>"27"}
{"id"=>"5"}
{"id"=>"11"}
[{"id"=>"9"}, {"id"=>"23"}, {"id"=>"11"}, {"id"=>"19"}, {"id"=>"7"}, {"id"=>"5"}, {"id"=>"25"}, {"id"=>"13"}, {"id"=>"15"}, {"id"=>"3"}, {"id"=>"21"}, {"id"=>"17"}, {"id"=>"31"}]
{"id"=>"17"}
{"id"=>"13"}
[{"id"=>"13"}, {"id"=>"7"}, {"id"=>"5"}]
[{"id"=>"9"}, {"id"=>"11"}, {"id"=>"19"}, {"id"=>"5"}, {"id"=>"25"}, {"id"=>"13"}, {"id"=>"15"}, {"id"=>"3"}, {"id"=>"21"}, {"id"=>"17"}]
[{"id"=>"9"}, {"id"=>"3"}]
[{"id"=>"21"}, {"id"=>"11"}, {"id"=>"7"}, {"id"=>"5"}, {"id"=>"25"}]
{"id"=>"5"}
[{"id"=>"25"}, {"id"=>"5"}, {"id"=>"3"}, {"id"=>"21"}]
{"id"=>"3"}
{"id"=>"11"}
[{"id"=>"13"}, {"id"=>"33"}, {"id"=>"7"}, {"id"=>"5"}, {"id"=>"37"}, {"id"=>"31"}]
[{"id"=>"13"}, {"id"=>"7"}, {"id"=>"5"}, {"id"=>"21"}]

Is any way to sort it to get:

arrays = all_arrays_here
hashes = all_hashes_here

All these are inside an Array.

Upvotes: 0

Views: 66

Answers (3)

the Tin Man
the Tin Man

Reputation: 160551

@BroiSatse did the same thing first, but I think it's important to be able to see what Ruby does....

Consider this:

foo = [[1], {a: 2}, %w[3 4], {b: 5, c: 6}].group_by{ |e| e.class }
foo # => {Array=>[[1], ["3", "4"]], Hash=>[{:a=>2}, {:b=>5, :c=>6}]}

Ruby's built-in group_by is made for just this sort of problem.

Building on that:

arrays, hashes = foo.values_at(Array, Hash)

arrays # => [[1], ["3", "4"]]
hashes # => [{:a=>2}, {:b=>5, :c=>6}]

values_at retrieves the values from a hash (in this case) in the order specified.

Upvotes: 2

Bibek Shrestha
Bibek Shrestha

Reputation: 34984

a = [
  [{"id"=>"3"}, {"id"=>"9"}],
  {"id"=>"27"},
  {"id"=>"5"},
  {"id"=>"11"},
  [{"id"=>"9"}, {"id"=>"23"}, {"id"=>"11"}],
  {"id"=>"17"}
]

arrays, hashes = a.inject([[], []]) do |accum, item|
  item.is_a?(Array) ? accum[0] << item : accum[1] << item
  accum
end

Thus you have arrays and hashes separated from the variable a

Edit: Prefer @BroiSatse's solution to this.

Upvotes: 0

BroiSatse
BroiSatse

Reputation: 44675

Assuming this data is in some kind of enumerable object you can do:

arrays, hashes = data.group_by(&:class).values_at(Array, Hash)

However it feels wrong. Most likely you rather need to wrap each hash within its own array (so you can later to double iteration). If this is the case:

data.map! {|array_or_hash| Array.wrap(array_or_hash)}

Upvotes: 3

Related Questions