Split into hash

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?

Thanks in advance

···

--
Posted via http://www.ruby-forum.com/.

Ok now i have

a = Hash.new
File.open('file').each do |line|
  b,c = line.split(/=/)
  a[b] = c
end

Which works, but im sure there are better ways out there?

···

--
Posted via http://www.ruby-forum.com/.

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..

Hash[*File.read(filename).scan(/^.*=.*$/).flatten]

HTH,
Sebastian

···

--
NP: Black Sabbath - Dirty Women
Jabber: sepp2k@jabber.org
ICQ: 205544826

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..

Hash[*File.read(filename).scan(/^.*=.*$/).flatten]

I believe that should be:

Hash[*File.read(filename).scan(/^(.*)=(.*)$/).flatten]

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

Felix

···

-----Original Message-----

Felix Windt wrote:

> From: Sebastian Hungerecker [mailto:sepp2k@googlemail.com]
> Hash[*File.read(filename).scan(/^.*=.*$/).flatten]

I believe that should be:

Hash[*File.read(filename).scan(/^(.*)=(.*)$/).flatten]

Yes, it should - sorry about that. Usually I test code before posting it.

···

--
NP: Porcupine Tree - Start Of Something Beautiful
Jabber: sepp2k@jabber.org
ICQ: 205544826

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]

I believe that should be:

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.

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]

I believe that should be:

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/

Thanks very much everyone, That's a great help

···

--
Posted via http://www.ruby-forum.com/.

Here's another one:

h = {}
File.foreach("file") do |line|
   h[$1]=$2 if /^([^=]*)=([^=]*)$/ =~ line
end

Kind regards

  robert

···

On 24.09.2007 11:11, Lee Jarvis wrote:

Thanks very much everyone, That's a great help