From you question it is very hard to tell what you want. Especially since the order you ask for is exactly the same one a normal sort would create.
I any case, here is a way of creating a "custom sort" order the way you wanted. The difference between this and a regular sort is that in this sort can make certain types of characters or sets of characters triumph others.
array = [
{color: '5 absolute'},
{color: '5.0'},
{color: '50 hello'},
{color: 'edge'}
]
p array.sort_by{|x| x[:color]} #=> [{:color=>"5 absolute"}, {:color=>"5.0"}, {:color=>"50 hello"}, {:color=>"edge"}]
# '50 hello' is after '5.0' as . is smaller than 0.
Solving this problem is a bit tricky, here is how I would do it:
# Create a custom sort order using regexp:
# [spaces, dots, digits, words, line_endings]
order = [/\s+/,/\./,/\d+/,/\w+/,/$/]
# Create a union to use in a scan:
regex_union = Regexp.union(*order)
# Create a function that maps the capture in the scan to the index in the custom sort order:
custom_sort_order = ->x{
x[:color].scan(regex_union).map{|x| [order.index{|y|x=~y}, x]}.transpose
}
#Sort:
p array.sort_by{|x| custom_sort_order[x]}
# => [{:color=>"5 absolute"}, {:color=>"50 hello"}, {:color=>"5.0"}, {:color=>"edge"}]