[code] reading a CSV file
-
Here's an example by Jim Foltz (he posted in GoogleGroups - Sketchup Developers),
but modified, module and method wrapped.I (Dan) also added:
- flexibility for a header row* setting a value delimiter in the method call.
Returning CSV data as an Array of record Arrays
Feel free to change the methodname to suit your taste.
module MyTopLevelNamespace #<--- you change this module MyPlugin #<--- you change this also class<<self def read_csv_to_array(file, relapath='.', basepath=Dir.getwd, delim=',', header=false) firstline=true data=[] IO.foreach("#{File.join(basepath,relapath,file)}") do |line| if header && firstline headrec = line.split(delim) firstline=false else record = line.split(delim) data << record end end # foreach # return ( header ? [headrec,data] ; data ) # end # def end # class self begin dirNow = Dir.getwd # save current dir subpath = 'relative/path/to/data' Dir.chdir(ENV['USER']+'/somesubdir') records = read_csv_to_array('filename.csv',subpath) Dir.chdir(dirNow) # restore the dir # # do stuff with array of record arrays # end end # module end # module
If you set header=true, then the returned array will have 2 elements:
-
the 1st will be the header row array (1 record), * the 2nd will be an multi-record array (an array of record arrays.)
Otherwise with the default (header=false,) -
the method would return just an array of record arrays.
EDIT: updated
Reordered arguments to method, all but file with defaults:
relapath (defaults to current dir ['.'])
basepath (defaults to current working dir. [Dir.getwd])
delim (defaults to comma. [','])
header (defaults to false.)
COMMUNITY CONTENT - Public Domain - Author claims no copyright.
Moderators may edit post / correct code snippet(s) at will. -
Returning CSV data as an Array of record Hashes
Feel free to change the methodname to suit your taste.
module MyTopLevelNamespace #<--- you change this module MyPlugin #<--- you change this also class<<self def read_csv_to_hash_array(file, relapath='.', basepath=Dir.getwd, delim=',', header=nil) firstline=true data=[] headrec=[] IO.foreach("#{File.join(basepath,relapath,file)}") do |line| if header.nil? && firstline headrec = line.split(delim) firstline=false else record = line.split(delim) data << record end end # foreach # use custom hash keys passed in header Array headrec = header unless header.nil? hasheddata=[] data.each do |rec| rechash={} headrec.each_with_index {|h,i| rechash[h.to_s]=rec[i] } hasheddata << rechash.dup end # each rec # return hasheddata # end # def end # class self begin dirNow = Dir.getwd # save current dir subpath = 'relative/path/to/data' Dir.chdir(ENV['USER']+'/somesubdir') records = read_csv_to_hash_array('filename.csv',subpath) Dir.chdir(dirNow) # restore the dir # # do stuff with array of record hashes # end end # module end # module
EDIT: updated
header argument
nil (Use firstrow from CSV file as Hash keys.)
['key1','key2',...] (Use Array strings as Hash keys.)Reordered arguments to method, all but file with defaults:
relapath (defaults to current dir ['.'])
basepath (defaults to current working dir. [Dir.getwd])
delim (defaults to comma. [','])
header (defaults to nil.)
COMMUNITY CONTENT - Public Domain - Author claims no copyright.
Moderators may edit post / correct code snippet(s) at will. -
Hi, Dan, I simply paste "module MyTopLevelNamespace" in to Ruby console window of SU, but the error comes.
Error: #<SyntaxError: (eval):978: compile error
(eval):978: syntax errorSo why?
By the way, can I use eclipse to run your code?
Thank you.
-
[code] reading a CSV file : FAQ
Fequently Asked Questions
- What if I have string data that has embeded commas ??
- Export your CSV from your spreadsheet using a delimiter other than comma. '||' or '$$' etc.* pass your custom delimiter to the method as the delim argument.
- How do I import from a TAB delimited datafile ??
Call the method and specify 9.chr for the delim argument.
COMMUNITY CONTENT - Public Domain - Author claims no copyright.
Moderators may edit post / correct code snippet(s) at will. -
@zps222 said:
Hi, Dan, I simply paste "module MyTopLevelNamespace" in to Ruby console window of SU, but the error comes. So why?
A module definition is a block statement. It's meant to be read by the interpreter.
The console is a line evaluation function.
You CAN make a module at the console by putting it all on 1 line, like:
module Zps222; def say_hello(); puts "Hello!"; end; end
YOU are supposed to choose YOUR OWNidentifier for a toplevel module name (namespace.)
Replace "MyTopLevelNamespace" with a unique name that YOU decide. (You can use Zps222, or whatever you want, as long as it is unique for YOU, and noone else will use it.)Also "MyPlugin", you change it to whatever name you want your plugin to be.
@zps222 said:
By the way, can I use eclipse to run your code?
Yes. This code is not Sketchup specific. It's just plain old standard Ruby.
Advertisement