我正在创建一个项目,我从网页上抓取数据以获取产品信息。 我的抓取方法返回一个嵌套数组,其中包含product_names,url和price的集合。我正在尝试使用嵌套数组来创建我的类Supplies的实例,其中包含名称,url和price的属性。嵌套数组在3个数组中的每个数组中具有相同数量的元素。
我希望@@ all返回集合中所有产品的实例数组,并设置其属性。
name_url_price = [[],[],[]]
class Catalog::Supplies
attr_accessor :name, :price, :url
@@all = []
def initialize(name_url_price)
count = 0
while count <= name_url_price[0].length
self.name = name_url_price[0][count]
self.url = name_url_price[1][count]
self.price = name_url_price[2][count]
@@all << self
count += 1
end
end
答案 0 :(得分:1)
这里出现了很多问题,但没有任何问题无法解决:
while count <= ...
循环未以end
终止。name_url_price[0]
是name_url_price
的第一个元素,因此name_url_price[0].length
可能总是为3。如果name_url_price
看起来更像[ [names], [urls], [prices] ]
,那么条件是正确的,但这是存储数据的一种奇怪且令人困惑的方式。while
循环在Ruby中非常罕见,您通常使用name_url_place.each do ... end
或来自Enumerable
的内容。name_url_price[count][0]
,name_url_price[count][1]
,...但是如果我误解了你的错误,请参阅(3)数据是结构化的。@@all << self
只是将同一个对象(self
)一遍又一遍地附加到@@all
。 @@all
最终将对同一个对象进行多次引用,并且该对象的属性将与while
循环的最后一次迭代匹配。initialize
方法用于初始化单个实例,让它创建一堆实例非常奇怪且令人困惑。对于你的班级来说,这样看起来会更常见,也更容易理解:
class Catalog::Supplies
attr_accessor :name, :price, :url
def initialize(name, url, price)
self.name = name
self.url = url
self.price = price
end
end
然后你的name_url_price
数组会更像这样:
name_url_price = [
[ 'name1', 'url1', 1 ],
[ 'name2', 'url2', 2 ],
[ 'name3', 'url3', 3 ],
[ 'name4', 'url4', 4 ]
]
并将耗材作为对象,无论列表会想要什么:
supplies = name_url_price.map { |a| Catalog::Supplies.new(*a) }
您还可以在name_url_price
中使用哈希:
name_url_price = [
{ name: 'name1', url: 'url1', price: 1 },
{ name: 'name2', url: 'url2', price: 2 },
{ name: 'name3', url: 'url3', price: 3 },
{ name: 'name4', url: 'url4', price: 4 }
]
然后像这样创建你的实例:
supplies = name_url_price.map do |h|
Catalog::Supplies.new(
h[:name],
h[:url],
h[:price]
)
end
或者像这样:
supplies = name_url_price.map { |h| Catalog::Supplies.new(*h.values_at(:name, :url, :price)) }