1. Computing

CSV Example: Complete Code

By

CSV Example: Complete Code

The following is the complete code for the "CSV Parsing" articles you can find here. As noted in the articles, Ruby does come with a better (faster, more correct, more complete) CSV library, so this code is not intended to be used in a production environment, but merely serve as an example.


#!/usr/bin/env ruby

# Parse a CSV file with column names.
# The first line of the file is assumed
# to be the column names, and also defines
# the number of columns.  Returns an
# array of hashes.
def csv(file)
  File.open(file) do|f|
    columns = f.readline.chomp.split(',')

    table = []
    until f.eof?
      row = f.readline.chomp.split(',')
      row = columns.zip(row).flatten
      table << Hash[*row]
    end

    return columns, table
  end
end

# Print a grade book from a CSV file.
# A grade book is alphabetized by first
# and last name and the columns are
# aligned properly.
columns, grades = csv(ARGV[0])

# Sort names by last name, then first name
grades.sort! do|a,b|
  a['Name'].split(' ').reverse.join(' ') <=> b['Name'].split(' ').reverse.join(' ')
end

# Determine column widths
column_widths = {}
columns.each do|c|
  column_widths[c] = [ c.length, *grades.map{|g| g[c].length } ].max
end

# Make the format string
format = columns.map{|c| "%-#{column_widths[c]}s" }.join(' | ')

# Print the table
puts format % columns
puts format.tr(' |', '-+') % column_widths.values.map{|v| '-'*v }

grades.each do|g|
  puts format % columns.map{|c| g[c] }
end

©2014 About.com. All rights reserved.