简体   繁体   中英

How to sort an array of hashes with multiple values?

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!

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 of other_ary using the <=> operator, then each of the second elements, etc… As soon as the result of any such comparison is non zero (ie the two corresponding elements are not equal), that result is returned for the whole array comparison.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM