Ruby:如何将对象的属性值从对象数组写入csv

时间:2013-09-09 07:08:16

标签: ruby arrays object csv

需要知道如何将对象的atrribute值从对象数组写入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 - 名称,重量,价格

row1 - 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:Rice的未定义方法`map',2,40:Item。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

要解决此问题,您有两种选择。

添加显式的return语句:

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

使用名为Parallel Assignment的东西

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

第二个选项也将返回一个包含所需值的数组,因为它是方法的最后一行。

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

编辑:

在您返回项目的代码中,当将其添加到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