Reputation: 2909
So I have an array of hashes:
[{"id":"30","name":"Dave"},
{"id":"57","name":"Mike"},
{"id":"9","name":"Kevin"},
...
{"id":"1","name":"Steve"}]
And I want to sort it by the id
attribute, so that it looks like this:
[{"id":"1","name":"Steve"},
{"id":"2","name":"Walter"},
...
{"id":"60","name":"Chester"}]
I'm assuming I use the sort_by
method but I'm not exactly sure how to do it.
Upvotes: 8
Views: 14727
Reputation: 160631
When I see incoming data like that, it's almost always a JSON string. Ruby doesn't automatically understand JSON, nor does it automatically know how to convert it, but Ruby does make it easy for us to convert from/to it:
require 'json'
json_data = '[{"id":"30","name":"Dave"},
{"id":"57","name":"Mike"},
{"id":"9","name":"Kevin"},
{"id":"1","name":"Steve"}]'
ary = JSON[json_data].sort_by{ |e| e['id'].to_i }
ary
# => [{"id"=>"1", "name"=>"Steve"}, {"id"=>"9", "name"=>"Kevin"}, {"id"=>"30", "name"=>"Dave"}, {"id"=>"57", "name"=>"Mike"}]
The only real trick here is:
JSON[json_data]
A lot of time you'll see people use JSON.parse(json_data)
, but the []
method is smart enough to recognize whether it's getting a String or an array or a hash. If it's a string it tries to parse it assuming it's incoming data. If it's an array or a hash, it converts it to a JSON string for output. The result is, using JSON[...]
simplifies the use of the class and makes it so we don't have to use parse
or to_json
.
Otherwise, using sort_by
is preferred over using sort
unless you are directly comparing two simple variables, like integer to integer, string to string or character to character. Once you have to dive into an object, or do some sort of calculation to determine how things compare, then you should use sort_by
. See Wikipedia's article on Schwartzian Transform to understand what's going on under the covers. It's a very powerful technique that can speed up sorting remarkably.
Upvotes: 6
Reputation: 51191
This should work:
array.sort_by { |hash| hash['id'].to_i }
In this case, sort_by
is preferred over sort
because it is more efficient. While sort
calls to_i
on every comparison, sort_by
does it once for each element in array and remembers the result.
Upvotes: 22
Reputation: 13921
Your Hash syntax is wrong, if they where symbols then it would look like this:
data = [
{id:"30", name:"Dave"},
{id:"57", name:"Mike"},
{id:"9", name:"Kevin"},
{id:"1", name:"Steve"}
]
sorted_data = data.sort_by{|x| x[:id].to_i}
Edit: Forgot the to_i, fixed. If the keys are strings the : way of defining a hash does not work, so we need hash-rockets instead:
data = [{"id"=>"30","name"=>"Dave"},
{"id"=>"57","name"=>"Mike"},
{"id"=>"9","name"=>"Kevin"},
{"id"=>"1","name"=>"Steve"}]
sorted_data = data.sort_by{|x| x['id'].to_i}
Upvotes: 2