#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2009
    Location
    oh, usa
    Posts
    13
    Rep Power
    0

    Output to file as 3 fields per row


    I'm trying to process an input file that looks like:

    AL,Alabama,Montgomery
    AK,Alaska,Juneau
    AZ,Arizona,Phoenix
    AR,Arkansas,Little Rock

    ... and out a file that looks like:

    "AL","Alabama","Montgomery"
    "AK","Alaska","Juneau"
    "AZ","Arizona","Phoenix"
    "AR","Arkansas","Little Rock"

    The code so far looks like this:

    myFile = Array.new
    myFile =File.readlines("C:/my_ruby_code/list_of_state_capitals_wState.txt")
    myFile.collect! {|line| line.strip}

    myFile.each do |line|
    puts line.split(/\,/).inspect
    myFile = line.split(/\,/).collect! {|element| '"'+element+'"'}
    puts myFile
    end

    File.open("C:/my_ruby_code/output_file.txt", "w") do |line|
    line.puts myFile
    end

    The only output I'm getting is this (the last line):

    "WY"
    "Wyoming"
    "Cheyenne"

    I'm a ruby nube so please, be kind. I know that line.split guy is separating each abbreviation, state and city into separate array slots but my brain hurts from trying to figure out a good one-liner like:

    oneLine = 3.times {line.split(/\,/).collect! {|element| '"'+element+'"'}}

    But, oneLine just ends up containing the number 3! Help please, thanks all!
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2008
    Posts
    41
    Rep Power
    42
    Originally Posted by nyteshade
    myFile = Array.new
    myFile =File.readlines("C:/my_ruby_code/list_of_state_capitals_wState.txt")
    myFile.collect! {|line| line.strip}
    First of all, you don't need to pre-declare the myFile Array. File::readlines returns an Array so the first line isn't necessary.

    The second and third line could be joined to create a more concise block. For example:
    Code:
    myFile = File.readlines("states.txt").collect {|line| line.strip }
    Originally Posted by nyteshade
    myFile.each do |line|
    puts line.split(/\,/).inspect
    myFile = line.split(/\,/).collect! {|element| '"'+element+'"'}
    puts myFile
    end

    File.open("C:/my_ruby_code/output_file.txt", "w") do |line|
    line.puts myFile
    end
    In this block of code, why are you reassigning the myFile variable?
    Also, Array#collect should be used over Array#collect! the exclamation mark tells Ruby to modify the contents of the Object it's called on. This isn't always what's returned.

    If I were you I would read the lines of the original file, then open another file Object for output (this could be the same file) and re-print the new data to that file. As for formatting the new lines you could use String#insert to add the new double quotes.

    For example in IRB:
    >> puts "AR,Arkansas,Little Rock".split(',').map {|x| x.insert(0, '"').insert(-1, '"') }.join(',')
    "AR","Arkansas","Little Rock"

    A full example:
    Code:
    #!/usr/bin/ruby -w
    
    def format(str)
      str.split(',').map {|text| text.strip.insert(0, '"').insert(-1, '"') }.join(',')
    end
    
    File.open('output.txt', 'w') do |file|
      DATA.each do |line|
        newline = format(line)
        
        file.puts newline
      end
    end
    
    __END__
    AL,Alabama,Montgomery
    AK,Alaska,Juneau
    AZ,Arizona,Phoenix
    AR,Arkansas,Little Rock
    You could also use gsub, or many other means of inserting the double quotes into the lines. Obviously this code could be simplified a lot so if any of it confuses you, just break it down and use as many lines as you need too rather than throwing it all on one like I have.

    On another note, please use code tags when posting. Thanks :-)
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2008
    Posts
    41
    Rep Power
    42
    Originally Posted by nyteshade
    oneLine = 3.times {line.split(/\,/).collect! {|element| '"'+element+'"'}}

    But, oneLine just ends up containing the number 3! Help please, thanks all!
    Forgot to add, this is because Integer#times returns an Integer (the amount of times the block has been iterated). In this case 3, so if 3.times {} returns 3 then that's the value you're assigning to the oneLine variable
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2009
    Location
    oh, usa
    Posts
    13
    Rep Power
    0

    okie-dokie


    Keep in mind I'm a nube to Ruby, it'll take me awhile to confirm what you've done. Thanks for the detail. I've only just finished chapter 5 of Peter Cooper's Beginning Ruby, sooo, I can't even spell 'map' yet; the method you created is more than I know so I need to read and test, bbl. Thanks again!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2009
    Location
    oh, usa
    Posts
    13
    Rep Power
    0

    regarding the irb line


    Code:
    >> puts "AR,Arkansas,Little Rock".split(',').map {|x| x.insert(0, '"').insert(-1, '"') }.join(',')
    "AR","Arkansas","Little Rock"
    What this is doing is taking the string, splitting it on the comma, mapping it over to |x| in the code block, performing the insert method by appending a double-quote at the beginning (0) and end (-1) of each 'map split element' and finally joining each 'map split element' using a comma. Yes? Ok, then I got that part and it works in IRB. I guess this confirms that your format method should also work. Let me try that now...bbl.



    Originally Posted by h4z3
    First of all, you don't need to pre-declare the myFile Array. File::readlines returns an Array so the first line isn't necessary.

    The second and third line could be joined to create a more concise block. For example:
    Code:
    myFile = File.readlines("states.txt").collect {|line| line.strip }

    In this block of code, why are you reassigning the myFile variable?
    Also, Array#collect should be used over Array#collect! the exclamation mark tells Ruby to modify the contents of the Object it's called on. This isn't always what's returned.

    If I were you I would read the lines of the original file, then open another file Object for output (this could be the same file) and re-print the new data to that file. As for formatting the new lines you could use String#insert to add the new double quotes.

    For example in IRB:
    >> puts "AR,Arkansas,Little Rock".split(',').map {|x| x.insert(0, '"').insert(-1, '"') }.join(',')
    "AR","Arkansas","Little Rock"

    A full example:
    Code:
    #!/usr/bin/ruby -w
    
    def format(str)
      str.split(',').map {|text| text.strip.insert(0, '"').insert(-1, '"') }.join(',')
    end
    
    File.open('output.txt', 'w') do |file|
      DATA.each do |line|
        newline = format(line)
        
        file.puts newline
      end
    end
    
    __END__
    AL,Alabama,Montgomery
    AK,Alaska,Juneau
    AZ,Arizona,Phoenix
    AR,Arkansas,Little Rock
    You could also use gsub, or many other means of inserting the double quotes into the lines. Obviously this code could be simplified a lot so if any of it confuses you, just break it down and use as many lines as you need too rather than throwing it all on one like I have.

    On another note, please use code tags when posting. Thanks :-)
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2009
    Location
    oh, usa
    Posts
    13
    Rep Power
    0

    got it - understand it!


    Originally Posted by nyteshade
    Code:
    >> puts "AR,Arkansas,Little Rock".split(',').map {|x| x.insert(0, '"').insert(-1, '"') }.join(',')
    "AR","Arkansas","Little Rock"
    Ok, I got it to work for me. I see how (and understand) you stacked those methods, sweet. Here's what I did (I'll experiment with gsub later). Thanks again.
    Code:
    def format(str)
      str.split(',').map {|text| text.strip.insert(0, '"').insert(-1, '"') }.join(',')
    end
    outFile = File.open("C:/my_ruby_code/output_file.txt", 'w') 
    File.open("C:/my_ruby_code/list_of_state_capitals_wState.txt", 'r') do |myFile|
        myFile.each do |line|
          newline = format(line)
          outFile.puts newline
        end
    end

IMN logo majestic logo threadwatch logo seochat tools logo