2014-03-12 145 views
2

我想用一個Ruby腳本替換遺留系統中的組件。該系統的一部分接受一個包含ASCII'0'和'1'的字符串,顯然表示位置的位域。然後它將這些位置轉換爲一串逗號分隔的兩個代碼(大部分是美國州)。紅寶石多個陣列比較

我有一個Ruby方法可以做到這一點,但它似乎並沒有像Ruby那樣做的最好方式。 Ruby有一噸的內置的遍歷方式和操作陣列,我覺得我不使用它們發揮到極致:

# input "0100010010" should return "AZ,PR,WY" 
def locations(bits)   
    # Shortened from hundreds for this post. :u? is for locations I have't figured out yet. 
    fields = [ :u?, :az, :de, :mi, :ne, :wy, :u?, :u?, :pr, :u? ] 
    matches = [] 
    counter = 0 
    fields.each { |f| 
    case bits[counter] 
     when '1' then matches << f 
     when '0' then nil 
     else raise "Unknown value in location bit field" 
    end 
    counter += 1 
    } 
    if matches.include(:u?) then raise "Unknown field bit set" end 
    matches.sort.join(",").upcase 
end 

這將是一個更好的方式來做到這一點?

似乎與「Ruby方式」有相反的變量浮動。我試圖尋找使用Array#map的方法,並且我發現沒有什麼明顯的。我也試着用Google搜索關於數組的Ruby成語。

回答

5
matches = fields.select.with_index { |_,i| bits[i] == '1' } 
# => [:az, :wy, :pr] 

要驗證bits僅持有0 S和1 S,你仍然可以做

raise "Unknown value in location bit field" if !bits.match(/^[01]*$/) 
+0

編輯此評論 - 我的錯誤。很好的答案! – joews

+0

優秀的方法。 –

1

您可以結合each_with_indexmapcompact

fields.each_with_index.map do |v,i| 
    v if bits[i] == '1' 
end.compact 

each_with_index返回每個每個值及其整數索引的迭代。

map使用傳遞塊的返回值爲每個輸入值生成輸出值。如果其相應的位被設置,該塊返回值,如果不是,則隱含地返回nil

compact返回刪除了所有nil值的輸出數組的副本。

欲瞭解更多詳情,請參閱文檔EnumerableArray

+0

也可以做'map.with_index'。 –

+0

重讀http://www.ruby-doc.org/core-2.1.1/Array.html#method-i-map頁面後,我看到了each_with_index,我認爲這將是最好的答案 – Sqeaky

2

使用Array#zipArray#reduce

bits.split('').zip(fields).reduce([]) do |a, (k, v)| 
    k == '1' ? a << v.to_s.upcase : a 
end.sort.join(',') 
# => "AZ,PR,WY 

說明:

1)split位轉換成字符數組:

bits.split('') # => ["0", "1", "0", "0", "0", "1", "0", "0", "1", "0"] 

2)zip兩個陣列以產生對數組(通過位置)

bits.split('').zip(fields) # => [["0", :u?], ["1", :az], ["0", :de], ["0", :mi], 
# ["0", :ne], ["1", :wy], ["0", :u?], ["0", :u?], ["1", :pr], ["0", :u?]] 

3)reduce陣列服用所需元素根據條件

.reduce([]) do |a, (k, v)| 
    k == '1' ? a << v.to_s.upcase : a 
end # => "[AZ,WY,PR] 

4)sort the r他們的元素得到期望的字符串

.sort.join(',') # => "AZ,PR,WY" 
+1

如果您可以在此示例中添加一點解釋,這將有所幫助。 – Fenton

+0

@SteveFenton:我已經添加了一些解釋,謝謝。 –

+0

@SteveFenton:順便提一下。我真的同意我們應該面對這樣一個採訪:http://www.stevefenton.co.uk/Content/Blog/Date/201403/Blog/If-You-Show-Me-Yours/ –