Как я могу создать экземпляры класса с данными из вложенного массива? - PullRequest
0 голосов
/ 26 мая 2018

Я создаю проект, в котором я собрал данные с веб-страницы для получения информации о продукте.Мой метод очистки возвращает вложенный массив с коллекцией product_names, urls и цен.Я пытаюсь использовать вложенный массив для создания экземпляров моего класса Supplies с атрибутами name, 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 голосов
/ 26 мая 2018

Здесь много чего не так, но ничего нельзя исправить:

  1. Хранение всех экземпляров в переменной класса немного странно.Создание экземпляров и отслеживание их вызывающим будет более распространенным и менее запутанным.
  2. Ваш while count <= ... цикл не завершается с end.
  3. Ваше условие цикла выглядит неправильно,name_url_price[0] является первым элементом name_url_price, поэтому name_url_price[0].length, вероятно, всегда будет три.Если name_url_price больше похоже на [ [names], [urls], [prices] ], то условие правильное, но это странный и запутанный способ хранения ваших данных.
  4. while циклы для итерации очень редки в Ruby, вы обычно используетеname_url_place.each do ... end или что-то из Enumerable.
  5. Индексирование вашего массива возможно обратное, вы хотите сказать name_url_price[count][0], name_url_price[count][1], ... Но смотрите (3) , еслиЯ неправильно понимаю, как структурированы ваши данные.
  6. Ваш @@all << self просто добавляет один и тот же объект (self) к @@all снова и снова.@@all будет заканчиваться множеством ссылок на один и тот же объект, и атрибуты этого объекта будут соответствовать последней итерации цикла while.
  7. Метод 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)) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...