Take an existing list of strings with whole and fractions of inch that includes the inch symbol:
['1"','1/2"','1 1/4"','1/4"','2"','1 1/8"']
Is there a best (rubyish, elegant, use of methods, object oriented) way in ruby to sort so it becomes
['1/4"','1/2"','1"','1 1/8"','1 1/4"','2"']
String#to_r
will conveniently ignore trailing garbage (such as "
):
The parser ignores leading whitespaces and trailing garbage.
so converting something like '1 1/2"'
to a number that will compare sensibly is a simple matter of:
s = '1 1/2"'
r = s.split.map(&:to_r).inject(:+)
Split the string into pieces, convert each to a Rational
using String#to_r
, and then add them up using Enumerable#inject
with a symbol argument. Clean and easy.
Once you have that, sorting is trivial:
array = ['1"','1/2"','1 1/4"','1/4"','2"','1 1/8"']
rationalized = lambda { |s| s.split.map(&:to_r).inject(:+) }
sorted = array.sort_by(&rationalized)
You don't have to use a lambda of course:
array.sort_by { |s| s.split.map(&:to_r).inject(:+) }
but I find that naming your little snippets of logic clarifies things.