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"}]
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>]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With