-1

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

福特,1996,蓝色,雪佛兰,2000,绿色

并让程序将值分配给具有三个参数的“汽车”对象:品牌、年份和颜色,稍后可以像这样访问:

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

等等任何数量的汽车。

在这个网站上环顾四周后,我发现了一些如何执行此操作的示例,但仅用于输出到另一个文件或字符串。谁能以尽可能简单的方式解释如何做到这一点?我对这种语言很陌生,很容易迷路。谢谢!
(对不起,我在编辑之前没有那么清楚)

4

2 回答 2

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)}
于 2013-02-25T05:30:16.213 回答
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(',')分割字符串,将我们在上一次迭代中得到的数组由三个元素分割成片段。然后我们迭代这些,展开键和值(按 3 分组)到一个哈希实例(剥离值,因为在用逗号分割字符串后还有空格)。,each_slice(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 
于 2013-02-25T05:53:08.913 回答