Reputation: 1123
I have an array of hashes which contains an id
field and a weight
field. I am able to sort it based on weight
but I also need to make sure that the id
field is sorted if there are duplicate weights. Below is the code snippet for reference.
# Input
arr = [{"id" => 10, "weight" => 23}, {"id" => 6, "weight" => 43}, {"id" => 12, "weight" => 5}, {"id" => 15, "weight" => 30}, {"id" => 11, "weight" => 5}]
arr.sort_by{|k| k["weight"]}
# Output: [{"id"=>12, "weight"=>5}, {"id"=>11, "weight"=>5}, {"id"=>10, "weight"=>23}, {"id"=>15, "weight"=>30}, {"id"=>6, "weight"=>43}]
# Expected output = [{"id"=>11, "weight"=>5}, {"id"=>12, "weight"=>5}, {"id"=>10, "weight"=>23}, {"id"=>15, "weight"=>30}, {"id"=>6, "weight"=>43}]
In the above example, id = 12
and id = 11
have the duplicate values. I need to have id = 11
before id = 12
in the array. I really appreciate some guidance on this. Thank you!
Upvotes: 1
Views: 552
Reputation: 106802
You can use Enumerable#sort_by
with an array too. Note the order of the values in the array.
arr.sort_by {|k| k.values_at("weight", "id") }
Quote from the docs of Array#<=>
about how comparison of array works:
Arrays are compared in an “element-wise” manner; the first element of
ary
is compared with the first one ofother_ary
using the<=>
operator, then each of the second elements, etc… As soon as the result of any such comparison is non zero (i.e. the two corresponding elements are not equal), that result is returned for the whole array comparison.
Upvotes: 4
Reputation: 26758
You can use Array#sort with the spaceship operator like so:
arr.sort do |a,b|
if a["weight"] == b["weight"]
a["id"] <=> b["id"]
else
a["weight"] <=> b["weight"]
end
end
Upvotes: 1