From: "Simon Kröger" Date: 2005-08-14T06:45:10+09:00 Subject: Re: no clue 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