1

需要知道如何将对象的属性值从对象数组写入 csv。

例如。

class Item
  attr_accessor :name, :weight, :price
end

def Item.create_item(name, weight, price)
  a = Item.new
  a.name = name
  a.weight = weight
  a.price = price
  return a
end

array_of_items = []

array_of_items << create_item(n1, w1, p1)
array_of_items << create_items(n2,w2,p2)
.....

我需要生成以下所需输出格式的 csv 文件

row0 - 名称、重量、价格

第 1 行 - n1,w1,p1

第 2 行 - n2、w2、p2

等等

上述任何指示都会有所帮助。

编辑:

根据反馈尝试了以下。

class Item
  attr_accessor :name, :weight, :price

  def initialize(name, weight, price)
      @name, @weight, @price = name, weight, price
  end

  def to_s
    [@name, @weight, @price].join(', ')
  end
end

itemlist = []
itemlist << Item.new("Rice", 2, 40)
itemlist << Item.new("Wheat", 3, 80)

CSV.open("items.csv", "wb") do |csv|
 itemlist.each do |i|
  csv << i
 end
end

这会引发以下错误 - NoMethodError: undefined method `map' for Rice, 2, 40:Item 。

如果我检查 itemlist.class,那就是 Array;itemlist[0].class 是 Item - 这里没有惊喜。我认为您说上面定义的 to_s 实例方法应该在将内容添加到 CSV 时处理打印问题,但这似乎不起作用。

4

2 回答 2

0

您可以按以下方式执行此操作:

require "csv"

class Item
  attr_accessor :name, :weight, :price
end

def Item.create_item(name, weight, price)
  a = Item.new
  [a.name = name,a.weight = weight,a.price = price]
end

CSV.open("/home/kirti/ruby/csv/test.csv", "wb") do |csv|
  csv << ['name' , 'weight', 'price']
  csv << Item.create_item(:foo, 23, 11)
end

输出:

name,weight,price
foo,23,11
于 2013-09-09T07:34:09.843 回答
0

ruby 方法总是返回最后一个值。您的方法 Item.create_item 返回 a.price,因为这是最后一个值。

要解决这个问题,你有两个选择。

添加显式返回语句:

def Item.create_item(name, weight, price)
  a = Item.new
  a.name = name
  a.weight = weight
  a.price = price
  return [name, weight, price]
end

使用称为并行分配的东西

def Item.create_item(name, weight, price)
  a = Item.new
  a.name, a.weight, a.price  = name, weight, price
end

第二个选项还将返回一个包含您想要的值的数组,因为它是该方法的最后一行。

Babai 的回答告诉您如何将值输出到 csv。

编辑:

在您的代码中,当您返回项目 a 时,它不知道在将其添加到 csv 时如何打印出来。解决它的方法是定义 to_s 方法,该方法在将内容添加到 csvs 或打印到屏幕时调用。

请注意,我还重写了函数 a 以使用实例变量和初始化函数。希望它不会增加太多混乱。

class Item
  attr_accessor :name, :weight, :price

  def initialize(name, weight, price)
      @name, @weight, @price = name, weight, price
  end

  def to_s
    [@name, @weight, @price].join(', ')
  end

end

array_of_items = []
array_of_items << Item.new('name_of_item', 'weight_of_item', 'price_of_item')

评论后编辑:

查看 CSV 模块的文档后,CSV 需要一个数组。有两种方法可以做到这一点。

任何一个:

CSV.open("items.csv", "wb") do |csv|
  itemlist.each do |item|
    csv << [item.name, item.weight, item.price] 
    # item.name works because we added the attr_accessor
  end
end

或者:

class Item
  def to_array
    [@name, @weight, @price] 
  end
end

CSV.open("items.csv", "wb") do |csv|
  itemlist.each do |i|
    csv << i.to_array 
  end
end
于 2013-09-09T14:11:03.117 回答