如何使用Ruby将CSV数据导入类参数?

时间:2013-02-25 04:59:36

标签: ruby csv

我正在尝试在Ruby中使用CSV库,并将.csv文件的值存储到对象参数中。例如,我希望能够解析看起来像这个样本的.csv文件:

Ford,1996,Blue,Chevy,2000,Green

并让程序将值赋给“car”对象,其中包含三个参数:make,year和color,可以在以后访问:

car1.make = "Ford"
car1.year = 1996"
car1.color = "Blue"
car2.make = "Chevy"
car2.year = "2000"
car2.color = "Green"

对于任何数量的汽车都是如此。

在浏览了这个网站之后,我找到了一些如何做到这一点的例子,但仅用于输出到另一个文件或字符串。任何人都可以解释如何以尽可能简单的方式做到这一点吗?我对这种语言很陌生,很容易迷失方向。谢谢!
(对不起,我在编辑之前没有那么清楚)

2 个答案:

答案 0 :(得分:1)

require "csv"

class Car
  attr_reader :make, :year, :color
  def initialize *args; @make, @year, @color = args end
end

array_of_cars =
CSV.read(path_to_csv_file)
.each_slice(3)
.map{|args| Car.new(*args.map(&:to_s))}

array_of_cars[0].make # => "Ford"
array_of_cars[0].year # => "1996"
array_of_cars[0].color # => "Blue"
array_of_cars[1].make # => "Chevy"
array_of_cars[1].year # => "2000"
array_of_cars[1].color # => "Green"

或者你可以忍受:

array_of_cars[0].make # => "Ford"
array_of_cars[0].year # => 1996
array_of_cars[0].color # => "Blue"
array_of_cars[1].make # => "Chevy"
array_of_cars[1].year # => 2000
array_of_cars[1].color # => "Green"

然后

array_of_cars =
CSV.read(path_to_csv_file)
.each_slice(3).map{|args| Car.new(*args)}

答案 1 :(得分:0)

str = "Ford, 1996, Blue, Chevy, 2000, Green"
keys = [:make, :year, :color]

str.split(',').each_slice(3).map { |m|
  Hash[keys.zip m.map(&:strip)]  
} 

# ⇒ [
# ⇒   [0] {
# ⇒     :color => "Blue",
# ⇒      :make => "Ford",
# ⇒      :year => "1996"
# ⇒   },
# ⇒   [1] {
# ⇒     :color => "Green",
# ⇒      :make => "Chevy",
# ⇒      :year => "2000"
# ⇒   }
# ⇒ ]

我们来看看代码。 str.split(',')使用,作为分隔符来分割字符串,each_slice(3)将前一次迭代中得到的数组切割成三个元素。然后我们迭代这些,展开键和值(按3分组)到散列实例(剥离值,因为在用逗号分割字符串后仍留有空格)。

如果您想要cars[0].make而不是cars[0][:make]访问元素,则需要进行小型修补:

class Hash
  def method_missing(m, *args)
    if self.has_key?(m)
      return self[m]
    else
      super
    end  
  end  
end