2016-08-03 49 views
-1

我想將一個數組分解爲一個數組數組。通過數組有條件地迭代

test_ary = %w(101 This is the first label 102 This is the second label 103 This is 
the third label 104 This is the fourth label) 

result = iterate_array(test_ary) 

預期輸出:

#⇒ [ 
# "101 This is the first label", 
# "102 This is the second label", 
# "103 This is the third label", 
# "104 This is the fourth label" ] 

我寫了下面的方法:

def iterate_array(ary) 
    temp_ary = [] 
    final_ary =[] 
    idx = 0 
    temp_ary.push ary[idx] 
    idx +=1 
    done = ary.length - 1 
    while idx <= done 
     if ary[idx] =~ /\d/ 
      final_ary.push temp_ary 
      temp_ary = [] 
      temp_ary.push ary[idx] 
     else 
      temp_ary.push ary[idx] 
     end 
     idx +=1 
    end 
    final_ary.push temp_ary 
    returned_ary=final_ary.map {|nested_ary| nested_ary.join(" ")} 
    returned_ary 
end 

我認爲必須有一個更簡單,更優雅的方式。有任何想法嗎?

+2

中號嗨,這將幫助你將包括預期的輸出,這將有助於清理一些格式錯誤。 – mwp

+0

對不起。我只是着手格式化。希望我把它清理乾淨(在Vlad的幫助下) - M –

回答

0

根據您的函數給出的輸出結果,使用%w(101 This is the first label 102 This is the second label 103 This is the third label 104 This is the fourth label).each { |x| puts x }或使用map我得到了相同的結果。如果您可以發佈您的預期輸出,這將有所幫助。

1

這將一次遍歷數組中的兩個元素,當右側是一個數字時「斷開」(切片)它(或者當它被寫入時,當右側不包含任何非零元素時)數字字符)。希望這可以幫助!

test_ary.slice_when { |_, r| r !~ /\D/ }.map { |w| w.join(' ') } 
+0

這是一個非常好用的正則表達式。但是,假設數組在數字時總是應該中斷。儘管如此,答案很好。 +1 – Vlad

+1

謝謝@Vlad。它對輸入做出了一些有力的假設,但我只能解決原始問題中可用的任何信息! – mwp

+0

謝謝mwp。我想我太依賴ruby-doc.org上的基本Array類文檔了。我在ruby-lang.org上找到了關於#slice_when和#slice_between的信息。但我很困惑:當我輸入Array.methods時,不應該slice_when,哪個Array應該從Enumerable繼承,顯示出來嗎?它不... –

3

我會用Enumerable#slice_before

test_ary.slice_before { |w| w =~ /\d/ }.map { |ws| ws.join(" ") } 
# => ["101 This is the first label", "102 This is the second label", "103 This is the third label", "104 This is the fourth label"] 

編輯:作爲@mwp說,可以讓這個更短:

test_ary.slice_before(/\d/).map { |ws| ws.join(" ") } 
# => ["101 This is the first label", "102 This is the second label", "103 This is the third label", "104 This is the fourth label"] 
+2

非常好!我喜歡這比slice_when更好。 slice_before可以接受一個模式參數,所以它可以簡化爲'words.slice_before(/ \ d /)'。 – mwp

+0

@mwp謝謝!我不知道。 – Dogbert

2
▶ test_ary.join(' ').split(/ (?=\d)/) 
#⇒ [ 
# [0] "101 This is the first label", 
# [1] "102 This is the second label", 
# [2] "103 This is the third label", 
# [3] "104 This is the fourth label" 
# ] 
+0

Thx muda。使用正則表達式有很長的路要走 –

+0

歡迎erel,但我無法理解你的意思。 – mudasobwa