From: William James Date: 2007-02-03T17:00:07+09:00 Subject: Re: Beginner questions: sorting csv files On Feb 2, 9:53 pm, Michael Sc wrote: > William James wrote: > > On Feb 2, 4:26 pm, Michael Sc wrote: > >> Thank you very much. I did not realize it was so simple. Do you know > >> how to refer to prior lines to make calculations? > > >> -- > >> Posted viahttp://www.ruby-forum.com/. > > > a = > > [ ['alloy', 1.414], > > ['malign', 1.732], > > ['smudge', 2.0], > > ['smack', 2.236] > > ] > > > 0.upto( a.size - 2 ) {|i| > > puts "Change from line #{i} to line #{i+1}:\ > > #{ (a[i+1][1] - a[i][1]) / a[i][1] * 100 }%" > > } > > Thank you very much. I just had one more question about this then. How > would I write this to its own csv file? > > require 'csv' > outfile = File.open('newfile.csv', 'wb') > x=CSV.open("oldfile.csv", "r") > x.sort_by{|a| a.values_at( 2,0,1 ) }.each{|a| outfile.print a } > outfile.close > > I tried outfile.p(doesn't work), outfile.print(takes out the commas) and > outfile.put(takes out the breaks). I know this should be incredibly > easy but I am clearly missing something. Before writing each record (i.e., each array of fields) to the file, it must first be converted to a proper csv string. The 'csv' package has a method for doing this, I presume. If you don't wan't to use that, try this: class Array def to_csv s = '' map { |item| str = item.to_s # Quote the string if it contains the field-separator or # a " or a newline or a carriage-return, or if it has leading or # trailing whitespace. if str.index( "," ) or /^\s|["\r\n]|\s$/.match(str) str = '"' + str.gsub( /"/, '""' ) + '"' end str }.join( "," ) end end puts [ 674, "yes", "Jones,Tom", 'foo"bar', " space " ].to_csv --- output ----- 674,yes,"Jones,Tom","foo""bar"," space "