Best way to fill in gaps within multidimensional array in Ruby -


i have multi-dimensional array similar example below want group using ruby's zip method. have working fine when each inner array has same number of elements, running problems when different lengths.

in example below, second set missing record @ 00:15. how fill in missing record?

what considering gap?

it's timestamp constitutes gap. take @ first code sample have comment gap being @ 00:15. other arrays have hash timestamp, consider "missing record" or "gap". timestamp other unique string fact 15 minutes apart irrelevant. values irrelevant.

the approach comes mind involves looping on arrays twice. first time build array of uniq timestamps, , second time fill in missing record(s) timestamp not present. i'm comfortable coding approach, seems little hacky , ruby seems surprise me elegant , concise solution.

i start this:

values = [   [     {:timestamp => "2011-01-01 00:00", :value => 1},     {:timestamp => "2011-01-01 00:15", :value => 2},     {:timestamp => "2011-01-01 00:30", :value => 3}   ],   [ # there's gap here @ 00:15     {:timestamp => "2011-01-01 00:00", :value => 1},     {:timestamp => "2011-01-01 00:30", :value => 3}   ],   [     {:timestamp => "2011-01-01 00:00", :value => 1},     {:timestamp => "2011-01-01 00:15", :value => 2},     {:timestamp => "2011-01-01 00:30", :value => 3}   ] ] 

i want end this:

values = [   [     {:timestamp => "2011-01-01 00:00", :value => 1},     {:timestamp => "2011-01-01 00:15", :value => 2},     {:timestamp => "2011-01-01 00:30", :value => 3}   ],   [ # gap has been filled nil value     {:timestamp => "2011-01-01 00:00", :value => 1},     {:timestamp => "2011-01-01 00:15", :value => nil},     {:timestamp => "2011-01-01 00:30", :value => 3}   ],   [     {:timestamp => "2011-01-01 00:00", :value => 1},     {:timestamp => "2011-01-01 00:15", :value => 2},     {:timestamp => "2011-01-01 00:30", :value => 3}   ] ] 

when arrays same size, values.transpose produce:

[   [    {:value=>1, :timestamp=>"2011-01-01 00:00"},     {:value=>1, :timestamp=>"2011-01-01 00:00"},     {:value=>1, :timestamp=>"2011-01-01 00:00"}   ],    [     {:value=>2, :timestamp=>"2011-01-01 00:15"},      {:value=>nil, :timestamp=>"2011-01-01 00:15"},     {:value=>2, :timestamp=>"2011-01-01 00:15"}   ],    [     {:value=>3, :timestamp=>"2011-01-01 00:30"},      {:value=>3, :timestamp=>"2011-01-01 00:30"},      {:value=>3, :timestamp=>"2011-01-01 00:30"}   ] ] 

the approach outlined correct, turns out ruby suited doing kind of approach elegantly. it, example:

stamps = values.map{ |logs| logs.map{ |row| row[:timestamp] } }.flatten.uniq.sort values.map!{ |logs| stamps.map { |ts| logs.select{ |row| row[:timestamp] == ts }.first || { :timestamp => ts, :value => nil } } } 

the first line gets list of unique timestamps (maps logs arrays of timestamps, flattens arrays single array, keeps uniques, , sorts timestamps).

the second line fills in gaps (loops through logs, , each timestamp in log use what's there if there's there, otherwise insert new nil-valued row).


Comments

Popular posts from this blog

java - SNMP4J General Variable Binding Error -

windows - Python Service Installation - "Could not find PythonClass entry" -

Determine if a XmlNode is empty or null in C#? -