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?
From: Sebastian Hungerecker [mailto:sepp2k@googlemail.com]
Sent: Sunday, September 23, 2007 11:43 AM
To: ruby-talk ML
Subject: Re: Split into hash
Lee Jarvis wrote:
> 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..
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: sepp2k@jabber.org
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.
David
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
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.
···
On Mon, 24 Sep 2007 04:41:29 +0900, David A. Black wrote:
Hi --
On Mon, 24 Sep 2007, Sebastian Hungerecker wrote:
Felix Windt wrote:
From: Sebastian Hungerecker [mailto:sepp2k@googlemail.com]
Hash[*File.read(filename).scan(/^.*=.*$/).flatten]
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.
--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/