Reputation: 29
I have an array of hashes with id and name. The names can either have digits + strings or strings only. The goal is to sort alphabetically and if there are digits in the name, sort them by digit value.
Given:
array = [{id: "1", name: "Lorem 100"},
{id: "2", name: "Lorem 101"},
{id: "3", name: "Lorem 101-A"},
{id: "4", name: "Lorem 101-B"},
{id: "5", name: "Lorem 2"},
{id: "6", name: "Ipsum (Lorems 55 & 55A)"},
{id: "7", name: "Dolor"},
{id: "8", name: "Sit"},
{id: "9", name: "Amet"}]
Sort like this:
sorted_array = [ {id: "9", name: "Amet"},
{id: "7", name: "Dolor"},
{id: "6", name: "Ipsum (Lorems 55 & 55A)"},
{id: "5", name: "Lorem 2"},
{id: "1", name: "Lorem 100"},
{id: "2", name: "Lorem 101"},
{id: "3", name: "Lorem 101-A"},
{id: "4", name: "Lorem 101-B"},
{id: "8", name: "Sit"}]
What I've tried:
Reaching out to this great community for any resource or suggestions that may help me solve this. Thank you!
Upvotes: 0
Views: 84
Reputation: 198324
array.sort_by { |hash|
hash[:name].split(/(\d+)/).map.with_index { |part, index|
index.odd? ? part.to_i : part
}
}
Split the name using consecutive digits as separator, using capture parentheses to keep separators (see String#split
); then change the separators (i.e. every odd element) into integers, so they can compare numerically rather than lexicographically. Thus, sort_by
will compare items such as ["Ipsum (Lorems ", 55, " & ", 55, "A)"]
. Array#<=>
does the intuitive thing, where ["Lorem ", 2]
comes before ["Lorem ", 101]
.
Upvotes: 1