如何使用嵌套数组中的数据创建类的实例?

时间:2018-05-25 23:54:49

标签: arrays ruby class object nested

我正在创建一个项目,我从网页上抓取数据以获取产品信息。 我的抓取方法返回一个嵌套数组,其中包含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

1 个答案:

答案 0 :(得分:1)

这里出现了很多问题,但没有任何问题无法解决:

  1. 将所有实例存储在类变量中有点奇怪。创建实例并让调用者跟踪它们会更常见,也不会让人感到困惑。
  2. 您的while count <= ...循环未以end终止。
  3. 您的循环条件看起来不对,name_url_price[0]name_url_price的第一个元素,因此name_url_price[0].length可能总是为3。如果name_url_price看起来更像[ [names], [urls], [prices] ],那么条件是正确的,但这是存储数据的一种奇怪且令人困惑的方式。
  4. 用于迭代的
  5. while循环在Ruby中非常罕见,您通常使用name_url_place.each do ... end或来自Enumerable的内容。
  6. 你的数组索引可能是倒退的,你想说name_url_price[count][0]name_url_price[count][1],...但是如果我误解了你的错误,请参阅(3)数据是结构化的。
  7. 您的@@all << self只是将同一个对象(self)一遍又一遍地附加到@@all@@all最终将对同一个对象进行多次引用,并且该对象的属性将与while循环的最后一次迭代匹配。
  8. initialize方法用于初始化单个实例,让它创建一堆实例非常奇怪且令人困惑。
  9. 对于你的班级来说,这样看起来会更常见,也更容易理解:

    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)) }