2016-08-03 20 views
-1

Ich möchte ein Array in ein Array von Arrays zu brechen.Iterate bedingt durch Array

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) 

Erwartete Ausgabe:

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

schrieb ich die folgende Methode:

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 

ich da denken muss ein einfacher und eleganter Weg. Irgendwelche Ideen?

+2

Hallo M, würde es helfen, wenn Sie würde die erwartete Ausgabe enthalten, würde es helfen, einige Ihrer Formatierungsfehler zu bereinigen. – mwp

+0

Sorry Leute. Ich bin gerade dabei, die Formatierung zu verstehen. Hoffentlich habe ich es aufgeräumt (w die Hilfe von Vlad) - M –

Antwort

0

Basierend auf dem Ausgang Ihrer Funktion gibt mir, mit %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 } oder mit map ich das gleiche Ergebnis. Es würde helfen, wenn Sie Ihre erwartete Ausgabe veröffentlichen können.

1

Dies wird durch das Array zwei Elemente auf einmal durchlaufen und "brechen" (schneiden) es, wenn die rechte Seite eine Zahl ist (oder wie es geschrieben wird, wenn die rechte Seite keine enthält Ziffern Zeichen). Hoffe das hilft!

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

Das ist eine ziemlich gute Verwendung einer Regex. Aber das nimmt an, dass das Array immer brechen sollte, wenn es numerisch ist. Gute Antwort trotzdem. +1 – Vlad

+1

Danke @Vlad. Es macht einige starke Annahmen über die Eingabe, aber ich kann nur mit den Informationen arbeiten, die in der ursprünglichen Frage verfügbar sind! – mwp

+0

Danke mwp. Ich schätze, ich verlasse mich zu sehr auf die grundlegenden Array-Klassendokumente auf ruby-doc.org. Ich habe Infos auf #slice_when und #slice_between auf der Seite ruby-lang.org gefunden. Aber ich bin verwirrt: Wenn ich Array.Methods eingeben, sollte nicht slice_when, welches Array von Enumerable erben sollte, auftauchen? Es tut nicht ... –

3

würde ich 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"] 

Edit: Wie @mwp sagte, können Sie dies noch kürzer machen:

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

Ganz nett! Ich mag das besser als slice_when. slice_before kann ein Musterargument nehmen, so dass es ein wenig zu 'words.slice_before (/ \ d /)' 'vereinfacht werden kann. – mwp

+0

@mwp danke! Das wusste ich nicht. – 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. Die Verwendung von Regex ist ein langer Weg –

+0

Willkommen Erel, ich kann nicht verstehen, was Sie gemeint haben. – mudasobwa