【发布时间】:2016-03-05 18:43:45
【问题描述】:
获取包含英寸符号的完整和分数英寸字符串的现有列表:
['1"','1/2"','1 1/4"','1/4"','2"','1 1/8"']
在 ruby 中有没有最好的(rubyish,优雅,使用方法,面向对象)的方式来排序,所以它变成了
['1/4"','1/2"','1"','1 1/8"','1 1/4"','2"']
【问题讨论】:
获取包含英寸符号的完整和分数英寸字符串的现有列表:
['1"','1/2"','1 1/4"','1/4"','2"','1 1/8"']
在 ruby 中有没有最好的(rubyish,优雅,使用方法,面向对象)的方式来排序,所以它变成了
['1/4"','1/2"','1"','1 1/8"','1 1/4"','2"']
【问题讨论】:
String#to_r 将方便地忽略尾随垃圾(例如"):
解析器会忽略前导空格和尾随垃圾。
因此,将 '1 1/2"' 之类的内容转换为可以进行合理比较的数字很简单:
s = '1 1/2"'
r = s.split.map(&:to_r).inject(:+)
将字符串拆分为多个片段,使用String#to_r 将每个片段转换为Rational,然后使用带有符号参数的Enumerable#inject 将它们相加。干净简单。
一旦你有了它,排序就很简单了:
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)
您当然不必使用 lambda:
array.sort_by { |s| s.split.map(&:to_r).inject(:+) }
但我发现命名你的小逻辑sn-ps可以澄清事情。
【讨论】:
:+ 在这里做的注入是什么?它是在拆分后添加碎片吗?
a.inject(:+) 对 a 的元素求和:inject "Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator."。