Ok guys, I have a file which looks something like this:
one=1
two=2
three=something
four=something else
I want to read each line into a hash, key=value…
I have tried something like
File.open(‘file’).each do |line|
line.split(/=/){|a,b| #something}
but that’s kind of how far i get… The only way i know of is reading
them all into an array of arrays and turning that into a hash, Is there
a better idea?
Also, the larger the file is, the better the OP’s solution (slightly
changed
by a chomp to get rid of newlines):
a = Hash.new
File.open(‘file’).each do |line|
b,c = line.chomp.split(/=/)
a[b] = c
End
will scale. Here’s a test with 100_000 key/value pairs:
$ for a in seq 1 100000; do echo “$a=$a” >> keyval; done
$ irb
irb(main):001:0> require ‘benchmark’
=> true
irb(main):002:0> Benchmark.bm do |x|
irb(main):003:1* x.report {
irb(main):004:2* a = Hash.new
irb(main):005:2> File.open(‘keyval’).each do |line|
irb(main):006:3* b,c = line.chomp.split(/=/)
irb(main):007:3> a[b] = c
irb(main):008:3> end
irb(main):009:2> }
irb(main):010:1> x.report {
irb(main):011:2* Hash[File.read(‘keyval’).scan(/^(.)=(.*)$/).flatten]
irb(main):012:2> }
irb(main):013:1> end
user system total real
0.640000 0.020000 0.660000 ( 0.665282)
5.410000 0.030000 5.440000 ( 5.433251)
=> true
irb(main):014:0>
Though for 10_000 pairs both versions run at about the same speed on my
system, and for 1_000 the regex scanner is slightly faster. So I suppose
it’ll depend on the use case.
HTH,
Sebastian
NP: Black Sabbath - Dirty Women
Jabber: [email protected]
ICQ: 205544826
Yes, it should - sorry about that. Usually I test code before posting
it.
I think it’s exactly (?) equivalent to:
Hash[*File.read(filename).scan(/[^=\n]+/)]
if you want to save the flattening operation.
No it’s not. The difference is when there are multiple equals signs on a
single line, the first solution will only split on one, while your
solution will split on all.