Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - sort array of hashes values (string) based on array order

Tags:

arrays

ruby

I have an array of hashes in the format shown below and I am attempting to sort the :book key of the hash based on a separate array. The order is not alphabetical and for my use case it cannot be alphabetical.

I need to sort based on the following array:

array = ['Matthew', 'Mark', 'Acts', '1John']

Note that I've seen several solutions that leverage Array#index (such as Sorting an Array of hashes based on an Array of sorted values) to perform a custom sort but that will not work with strings.

I've tried various combinations of sorting with Array#sort and Array#sort_by but they don't seem to accept a custom order. What am I missing? Thank you in advance for your help!

Array of Hashes

[{:book=>"Matthew",
  :chapter=>"4",
  :section=>"new_testament"},
 {:book=>"Matthew",
  :chapter=>"22",
  :section=>"new_testament"},
 {:book=>"Mark",
  :chapter=>"6",
  :section=>"new_testament"},
 {:book=>"1John",
  :chapter=>"1",
  :section=>"new_testament"},
 {:book=>"1John",
  :chapter=>"1",
  :section=>"new_testament"},
 {:book=>"Acts",
  :chapter=>"9",
  :section=>"new_testament"},
 {:book=>"Acts",
  :chapter=>"17",
  :section=>"new_testament"}]
like image 652
Kurt W Avatar asked Oct 16 '25 15:10

Kurt W


1 Answers

You can use sort_by with index

arr = [{a: 1}, {a: 3}, {a: 2}] 

order = [2,1,3]  

arr.sort_by { |elem| order.index(elem[:a]) }                                           
# => [{:a=>2}, {:a=>1}, {:a=>3}]  

You can make it slightly faster by indexing the list of elements you want to order by:

order_with_index = order.each.with_object.with_index({}) do |(elem, memo), idx|
  memo[elem] = idx
end

then instead of order.index(<val>) use order_with_index[<val>]

like image 81
max pleaner Avatar answered Oct 18 '25 05:10

max pleaner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!