2016-07-19 10 views
0

Ich versuche, einige Ausfallzeiten Berechnungen für eine Anwendung zu tun. Was ich habe, ist eine riesige Reihe von Hashes, die zeigen, wenn verschiedene Teile der Anwendung heruntergefahren waren. Der Hash enthält eine Startzeit und eine Endzeit. Das Problem ist, dass sich einige dieser Ausfallzeiten überschneiden können. Wie kann ich das Array von Hashes durchlaufen und Zeitintervalle finden, die sich überschneiden?Finden und reduzieren überlappende Zeitintervalle in Ruby-Array

times = [{"timefrom"=>1461693247, "timeto"=>1461693307}, 
     {"timefrom"=>1462363987, "timeto"=>1462364607}, 
     {"timefrom"=>1462364037, "timeto"=>1462366037}] 

So zum Beispiel, angesichts der obigen Anordnung, und times[1]times[2] überlappen. Im Idealfall möchte ich sie so zusammenführen, dass sie einen langen Ausfall bilden. I.E.

times[1] = { "timefrom" => times[1]["timefrom"], "timeto" => times[2]["timeto"] } 
+0

könnten mehr als 2 Zeitscheiben überlappen? Ist eine Eingabe nach "timefrom" sortiert? – mudasobwa

+0

@ Mudasobwa in der Theorie könnten sie alle überlappen. Super unwahrscheinlich, aber sie könnten. Und ja, sortiert nach 'timefrom' – Zack

+1

Willkommen bei Stack Overflow. Wir würden gerne Ihre Bemühungen sehen, das Problem zu lösen. Ohne dass es so aussieht, als würden Sie uns bitten, den Code für Sie zu schreiben. Bitte lesen Sie "[fragen]" einschließlich der verlinkten Seiten. Auch http://meta.stackoverflow.com/q/261592/128421 ist nützlich zu lesen. –

Antwort

1

Ich verstehe die Elemente g (Hashes) von times von g["timefrom"] geordnet.

def combine_times(times) 
    times[1..-1].each_with_object([times.first]) do |g,a| 
    if g["timefrom"] < a.last["timeto"] 
     a[-1]["timeto"] = [ a[-1]["timeto"], g["timeto"] ].max 
    else 
     a << g 
    end 
    end 
end 

times = [{"timefrom"=>1461693247, "timeto"=>1461693307}, 

     {"timefrom"=>1462363987, "timeto"=>1462364607}, 
     {"timefrom"=>1462364037, "timeto"=>1462366037}] 

Der Zeilenabstand zeigt, wie die Elemente der times gruppiert werden sollen.

combine_times(times) 
    #=> [{"timefrom"=>1461693247, "timeto"=>1461693307}, (times[0]) 
    # {"timefrom"=>1462363987, "timeto"=>1462366037}] (combines times[1..2]) 

Ein weiteres Beispiel:

times = [{"timefrom"=>10, "timeto"=>20}, 
     {"timefrom"=>12, "timeto"=>15}, 

     {"timefrom"=>22, "timeto"=>30}, 
     {"timefrom"=>28, "timeto"=>32}, 
     {"timefrom"=>29, "timeto"=>29}, 

     {"timefrom"=>32, "timeto"=>40}, 

     {"timefrom"=>42, "timeto"=>50}, 
     {"timefrom"=>43, "timeto"=>46}] 

combine_times(times) 
    #=> [{"timefrom"=>10, "timeto"=>20}, (combines times[0..1]) 
    # {"timefrom"=>22, "timeto"=>32}, (combines times[2..4]) 
    # {"timefrom"=>32, "timeto"=>40}, (times[5]) 
    # {"timefrom"=>42, "timeto"=>50}] (combines times[6..7]) 
+0

Schön! Nach Ihrer Lösung konnte ich eine Perl-Lösung verbessern, an der ich arbeitete. –