0

I have an array of hashes like this:

items = [{"id"=>"123", "code"=>"abc","name"=>"test", "type"=>["good"]},
   {"id"=>"555", "code"=>"ddd","name"=>"foo", "type"=>["better"]},
   {"id"=>"098", "code"=>"zyx","name"=>"bar", "type"=>["best"]}]

I am trying to sort each hash within the array by the key.

I tried this:

items.each { |item| item = item.sort.to_h }

It returns the same result:

 [{"id"=>"123", "code"=>"abc", "name"=>"test", "type"=>["good"]},
 {"id"=>"555", "code"=>"ddd", "name"=>"foo", "type"=>["better"]},
 {"id"=>"098", "code"=>"zyx", "name"=>"bar", "type"=>["best"]}]

but when I try this:

items[0].sort.to_h

this is the result:

 {"code"=>"abc", "id"=>"123", "name"=>"test", "type"=>["good"]}

So it looks like when I call the individual elements within items using items[x] where x is an index value within the array, it sort it. But I need a solution to iterate through each element doing that and saving the sort.

Any thoughts?

sawa
  • 165,429
  • 45
  • 277
  • 381
adbarads
  • 1,253
  • 2
  • 20
  • 43

2 Answers2

1

I solved it with this:

items.map { |item| item.sort.to_h } 

Thanks @SagarPandya and @Dark

adbarads
  • 1,253
  • 2
  • 20
  • 43
0

If, as in the example, all the hashes have the same keys, it would be faster to perform a single sort on the keys.

sorted_keys = items.first.keys.sort
  #=> ["code", "id", "name", "type"]
items.map { |item| sorted_keys.each_with_object({}) { |k,h| h[k] = item[k] } }
  #=> [{"code"=>"abc", "id"=>"123", "name"=>"test", "type"=>["good"]},
  #    {"code"=>"ddd", "id"=>"555", "name"=>"foo", "type"=>["better"]},
  #    {"code"=>"zyx", "id"=>"098", "name"=>"bar", "type"=>["best"]}]

The last line could alternatively be written

items.map { |item| sorted_keys.zip(item.values_at(*sorted_keys)).to_h }
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100