"sort_by" does not work with mixed arrays (number and strings) using Crystal 0.30.1 [5e6a1b672] (2019-08-12)
Examples:
### Works
test = [ [0, 1.23], [1, 1.10], [2, 1.15] ]
puts test.sort_by { |x| x[1] }
### Fails
test = [ ["a", 1.23], ["b", 1.10], ["c", 1.15] ]
puts test.sort_by { |x| x[1] }
### ERROR MESSAGE:
In /usr/share/crystal/src/number.cr:176:10
176 | self > other ? 1 : (self < other ? -1 : 0)
^
Error: no overload matches 'Float64#>' with type (Float64 | String)
Overloads are:
Mixed arrays type is the union of the elements types, that is the reason it cant find a method to
compare with a string. In the first case it works because Floats and Integers can be compared.
You should cast it.
test = [ ["a", 1.23], ["b", 1.10], ["c", 1.15] ]
puts test.sort_by { |x| x[1].as(Float64) }
Even better than casting it is to make so that it isn't needed in the first place. If you want typing that is aware of positions like that, use Tuples instead of arrays, or a specialized class.
An example of the Tuple advice:
test = [{"a", 1.23}, {"b", 1.10}, {"c", 1.15}]
puts test.sort_by { |x| x[1] }