2016-03-05 56 views
-1

,要考慮與整體英寸的分數,其中包括英寸符號串的現有列表:如何最好地排序在紅寶石分數的字符串列表?

['1"','1/2"','1 1/4"','1/4"','2"','1 1/8"']

是否有一個最好的(rubyish,優雅,使用方法,面向對象)的紅寶石的排序方式因此它成爲

['1/4"','1/2"','1"','1 1/8"','1 1/4"','2"']

回答

4

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) 

您不必使用過程中的拉姆達:

array.sort_by { |s| s.split.map(&:to_r).inject(:+) } 

但我發現,命名你的邏輯澄清的一點片段的東西。

+0

看起來不錯。爲了清晰和可重用,我同意使用片段或方法來封裝邏輯。感謝您的解釋並澄清to_r在參考文獻中所做的工作。用':+'在這裏做什麼注入?是否在分割之後添加了這些部分? – Streamline

+0

是的,'a.inject(:+)'彙總'a'的元素:inject' [「通過應用二進制操作來組合枚舉的所有元素,由塊或命名方法或操作符的符號指定。 「](http://ruby-doc.org/core-2.3.0/Enumerable.html#method-i-inject)。 –