面向对象和解析csv

时间:2011-09-29 22:42:43

标签: ruby

我必须解析csv文件,该文件包含他们订购的客户和产品。客户可以重复使用不同的产品。我必须得到他们订购的所有独特客户和产品。然后打印出每个客户和那里的产品。我被要求以面向对象的方式这样做 1)我应该创建一个客户对象,并将产品作为属性 2)只需使用foreach编写程序并循环并将客户和产品存储在哈希中并打印出来。

什么让我失望的是我被要求以面向对象的方式做到这一点。如果通过创建对象来实现如何在内存中存储自定义对象?因此,如果我第二次遇到客户,我必须添加产品,最后我必须遍历所有对象并将其打印出来。对不起,我的英语不好,感谢阅读一个很长的问题和帮助。

2 个答案:

答案 0 :(得分:1)

如何在内存中存储自定义对象?通过创建对象并将其保存在列表,哈希或其他任何合适的对象中。 (可能是哈希,密钥是您在CSV中具有的唯一值,而值将是产品集合。)

被要求以“面向对象的方式”这样做是有点武断的。

答案 1 :(得分:0)

如果您使用的是FasterCSV或Ruby 1.9,则可以扩展解析器,允许您将每个CSV行映射到自定义对象。

# http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html#method-c-load
# http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html#method-c-dump
# https://github.com/JEG2/faster_csv/blob/master/test/tc_serialization.rb
require 'csv'

class Person
  attr_accessor :id, :name, :email

  def self.csv_load(meta, headers, row)
    person = Person.new
    headers.each.with_index { |h,i|
      person.send "#{h}=", row[i]
    }
    person
  end

  def self.parse(csv)
    meta = "class,#{self.to_s}\n"
    CSV.load("#{meta}#{csv}")
  end

  def dump
    self.class.dump([self])
  end

  def self.dump(people, io='', options={})
    CSV.dump(people, io, options).strip
  end

  def self.csv_meta
    []
  end

  def csv_headers
    %w(id name email)
  end

  def csv_dump(headers)
    headers.map { |h| self.instance_variable_get "@#{h}" }
  end

end

CSV_DUMP = <<-CSV
class,Person
id=,name=,email=
1,"First Dude",dude@company.com
2,"Second Dude",2nddude@company.com
3,"Third Dude",3rddude@company.com
CSV

CSV_INPUT = <<-CSV
id,name,email
1,"First Dude",dude@company.com
2,"Second Dude",2nddude@company.com
3,"Third Dude",3rddude@company.com
CSV

CSV_DUMP2 = <<-CSV
class,Person
#{CSV_INPUT}
CSV

people = Person.parse(CSV_INPUT)
puts people.inspect
dumped =  Person.dump(people)
puts dumped
puts "----"
puts Person.parse(dumped).inspect