tags:

views:

86

answers:

4

I have the following text which will always follow the same format:

 1
 "13"
 "241"
 "Rabun"
 "06"
 "County"

 2
 "13"
 "281"
 "Towns"
 "06"
 "County"

I would like to assign each section to a hash like:

locality= {:id => "", :fips1 => "", :fips2 => "", :county => "", :stateid => "", :type => ""}

How would I go about doing this in Ruby? Any help is greatly appreciated.

A: 

for each section, use a regular expression with groups corresponding to each entry in the section, then simply create hash table as you described from these groups.

akonsu
+1  A: 
fields = [:fips1,:fips2,:county,:stateid,:type]
arraywithhashes = yourtextdata.split("\n\n").map { |loc|
    Hash[
        [[:id,loc[/\d+/]]] +
        fields.zip(loc.scan(/"([^"]+)"/).map &:first)
    ]
}

If you add new fields to your file, the only you'll need to edit is to add it to fields.

Nakilon
I wish I knew Ruby
willcodejavaforfood
@willcodejavaforfood: Then learn it! After a while you'd rather starve than code Java...
Lars Haugseth
The data is coming from a text file so if I dotextfile = File.open("filename.dat")arraywithhashes = textfile.split("\n\n").map { |loc|I get a NoMethodError.
Mike
@Lars Haugseth - I'm trying to! Even joined a Open Source project :)
willcodejavaforfood
@Mike, `file = File.open('filename.dat'); textfile = file.read; file.close` or `textfile = File.open('filename.dat'){|f|f.read}` or `textfile = File.read('filename.dat')`
Nakilon
This just gives me the 1st text block of the text file.It doesn't seem to loop through the rest of the text blocks.
Mike
@Mike, check your file to have `\n\n` delimeter between blocks. If it is another, edit `split` parameters.
Nakilon
Yes. it does have \n\n delimeters and still no luck. This seems to be a very generic solution but it's not working out for me.
Mike
OK, your file had `\n \n `. Hex-viewers are usefull.
Nakilon
Thanks for your help Nakilon. It worked great! Thanks for taking the extra time to look at the txt file too. I've added a hex-viewer to my toolset now.
Mike
A: 
locality.each_key { |k| locality.store(k, "foo") }

Another newbie-ish person here, but that might be a start for you.

NiDeep
A: 

You might want to consider using a Struct instead of a Hash.

Locality = Struct.new(:id, :fips1, :fips2, :county, :stateid, :type)
localities = []
DATA.each_slice(7) do |chunk|
    chunk.pop if chunk.size == 7 
    localities << Locality.new(*chunk.map{|line| line.scan(/\w+/) })
end

p localities # => [#<struct Locality id=["1"], fips1=["13"], fips2=["241"], etc. 
puts localities[1].fips2 # => 281

__END__
1
 "13"
 "241"
 "Rabun"
 "06"
 "County"

 2
 "13"
 "281"
 "Towns"
 "06"
 "County"
  • each_slice(7) takes 7 lines of DATA (the stuff after __END__ ).

  • The last line is removed unless there are only six lines (the last 'record').

  • A cleaned-up copy of the remaining lines is made. With these values a new Locality is created and added to an array

steenslag