Reputation: 89
I have a list of names in my DB and I need to sort them alphabetically. However, I need to show the greek letters first, and then the latin ones. For example, I have:
[Jale, Βήτα, Άλφα, Ben]
and I need to order it like this:
[Άλφα, Βήτα, Ben, Jale]
Any suggestions would be much appreciated :)
Upvotes: 2
Views: 424
Reputation: 132407
I gave one solution above. Another approach is to partition the names into greek and latin, then sort within those groups, then flatten the two arrays into one:
>> names.partition{|name| name !~ /^\w+$/}.map(&:sort).flatten
=> ["Άλφα", "Βήτα", "Ben", "Jale"]
This might be a little more elegant and understandable than my other solution, but it is less flexible. Note that name !~ /\w+$
will return something like true
if the name has non-latin characters, ie, is greek.
Upvotes: 0
Reputation: 132407
I like to solve these problems by playing around in irb. Here's one way you could go about finding this solution. First, we'll define our test array:
>> names = %w{Jale Βήτα Άλφα Ben}
=> ["Jale", "Βήτα", "Άλφα", "Ben"]
To solve this, let's first transform the array into 2-tuples which contain a flag indicating whether the name is greek or not, and then the name itself. We want the flag to be sortable, so we'll first find a regex match for latin-only characters, and coerce it to be a string.
>> names.map{|name| [(name =~ /^\w+$/).to_s, name]}
=> [["0", "Jale"], ["", "Βήτα"], ["", "Άλφα"], ["0", "Ben"]]
Then we'll sort the 2-tuples:
>> names.map{|name| [(name =~ /^\w+$/).to_s, name]}.sort
=> [["", "Άλφα"], ["", "Βήτα"], ["0", "Ben"], ["0", "Jale"]]
We now have a sort order where we have first the greek names, then the latin names. We can shorten this into our solution:
>> names.sort_by{|name| [(name =~ /^\w+$/).to_s, name]}
=> ["Άλφα", "Βήτα", "Ben", "Jale"]
Upvotes: 1