porterhaus porterhaus - 4 months ago 12
Ruby Question

Ruby sorting array order by integer in string

I've got a file that I read in the values from and place into an array so I can sort them:

input.txt

#75 - Hamilton Ave.
#12A - Long Road
#12B - Long Road
#120 - Curvy Road


My ruby:

result = []
file = open("input.txt").each do | line |
result << line
end
puts result.sort_by {|x| x.to_i}.reverse


I want to sort by the integer value in the string. However the order comes out as:

#12A - Long Road
#12B - Long Road
#120 - Curvy Road
#75 - Hamilton Ave.


Instead of:

#12A - Long Road
#12B - Long Road
#75 - Hamilton Ave.
#120 - Curvy Road


Should I be using some sort of regex to eval the string when sorting?

Answer

Use a regular expression like /\d+/ to extract the digits from the string and to_i to turn it into an integer, e.g.:

input.each_line.sort_by {|line| line[/\d+/].to_i }

To keep 12A before 12B, return an array from the block, e.g. [ line[/\d+/].to_i, line ]. This way, if two lines have the same integer, it will order those two lines alphabetically. This assumes there will only be a # before the digits in question, and that each line will have at least one digit.

input = <<END
#75 - Hamilton Ave.
#12A - Long Road
#12B - Long Road
#120 - Curvy Road
END

result = input.each_line.sort_by do |line|
  [ line[/\d+/].to_i, line ]
end

p result
# => [ "#12A - Long Road\n",
#      "#12B - Long Road\n",
#      "#75 - Hamilton Ave.\n",
#      "#120 - Curvy Road\n" ]

Throw map(&:chomp) in there if you want to get rid of the \ns.