data.each{ |j, line|
k, v = -2, 0
while (v = line.index(58, k))
h5[j][line[(k+2)...v].intern] =
line[(v+2)...(k = line.index(44, v) || line.length)]
end
}
Ok, lets walk this trough:
j is just the key in the outer hash.
line looks like:
"x_position: 200, y_position: 400, z_position: 300"
k is the index of the key (like 'x_position') in the line
v is the index of the value (like '200') in the line
58 is the ascii number of the char ':'
44 is the ascii number of the char ','
#index returns the index of the char in the string or nil
if no such char exists (after the index given as second
parameter)
while there is another ':' in the string
add key from last ',' to ':' => value from ':' to next ','
end
the +2 is there to skip the (',' or ':') and the space.
the initial k = -2 is there because no ',' is there to skip
at the beginning.
One is loosing readability of code if optimizing for speed
has top priority - even in ruby.
data.each{|j, line|
line.split(',').each{|kv|
k, v = kv.split(':')
h6[j][k.strip.intern] = v.strip
}
}
is much nicer, but look at the numbers:
user system total real
inject 4.672000 0.015000 4.687000 ( 5.281000)
scan 5.250000 0.063000 5.313000 ( 5.312000)
eval 6.140000 0.047000 6.187000 ( 6.219000)
tmp 4.407000 0.062000 4.469000 ( 4.469000)
index 0.375000 0.000000 0.375000 ( 0.375000)
split 10.625000 0.141000 10.766000 ( 10.781000)
true
cheers
Simon