Chezhian Chezhian - 4 months ago 8
Ruby Question

sort_by array of hashes is not giving expected results in ruby

I have the below array

arr = [
{ nbr: "979276030", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "03/23/2016 12:00 AM", name: "Brad Pacocha" },
{ nbr: "910482832", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "08/23/2015 12:00 AM", name: "Aracely Bogan" },
{ nbr: "819205275", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "09/02/2015 12:00 AM", name: "Kelli Moore" },
{ nbr: "755667162", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "10/16/2015 12:00 AM", name: "Trace Auer" },
{ nbr: "561189198", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "01/11/2016 12:00 AM", name: "Geoffrey Will" },
{ nbr: "429905984", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "04/25/2016 12:00 AM", name: "Martine Berge" },
{ nbr: "421919042", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "02/26/2016 12:00 AM", name: "Jewel Bailey" },
{ nbr: "274874145", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "04/19/2016 12:00 AM", name: "Wendell Tremblay" },
{ nbr: "254548319", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "01/16/2016 12:00 AM", name: "Dewitt Ritchie" },
{ nbr: "250154069", des: "CONF NO COST 30 Refi Plus <= 105 SM SRVR", status: "2C", milestone: "Processing", dt_time: "10/12/2015 12:00 AM", name: "Lisette Wehner" }
]

sort_arr = arr.sort_by { |h| h[:des] }

puts arr
puts '*'*100
puts sort_arr


I am expecting the sorted result should be the same as my source array, as the key has same value for all the hashes

But I am getting the below result

{:nbr=>"250154069", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"10/12/2015 12:00 AM", :name=>"Lisette Wehner"}
{:nbr=>"910482832", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"08/23/2015 12:00 AM", :name=>"Aracely Bogan"}
{:nbr=>"819205275", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"09/02/2015 12:00 AM", :name=>"Kelli Moore"}
{:nbr=>"755667162", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"10/16/2015 12:00 AM", :name=>"Trace Auer"}
{:nbr=>"561189198", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"01/11/2016 12:00 AM", :name=>"Geoffrey Will"}
{:nbr=>"429905984", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"04/25/2016 12:00 AM", :name=>"Martine Berge"}
{:nbr=>"421919042", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"02/26/2016 12:00 AM", :name=>"Jewel Bailey"}
{:nbr=>"274874145", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"04/19/2016 12:00 AM", :name=>"Wendell Tremblay"}
{:nbr=>"254548319", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"01/16/2016 12:00 AM", :name=>"Dewitt Ritchie"}
{:nbr=>"979276030", :des=>"CONF NO COST 30 Refi Plus <= 105 SM SRVR", :status=>"2C", :milestone=>"Processing", :dt_time=>"03/23/2016 12:00 AM", :name=>"Brad Pacocha"}


The first and last hash get swapped.

Is that a valid result? What is the reason for such a behavior?

Answer

Ruby's Array#sort_by uses an efficient implementation of quicksort.

Quicksort is a comparison sort, meaning that it can sort items of any type for which a "less-than" relation (formally, a total order) is defined. In efficient implementations it is not a stable sort, meaning that the relative order of equal sort items is not preserved. - Wikipedia Quicksort Article