Я новичок в Ruby, и мне нужно экспортировать информацию в CSV. Я написал этот код, и мне это не очень нравится. Я не знаю, как я могу реорганизовать его и избавиться от вложенных циклов.Рефакторинг вложенных циклов в Ruby-методе, который экспортируется в CSV
Мои отношения следующие: у Ордена есть много движений, у Move есть много остановок.
Мне нужно экспортировать все это в CSV, поэтому у меня будет несколько строк для одного и того же заказа!
def to_csv
CSV.generate(headers: true) do |csv|
csv << h.t(self.first.exported_attributes.values.flatten) # headers
self.each do |order|
order.moves.map do |move|
move.stops.map do |stop|
order_data = order.exported_attributes[:order].map do |attributes|
order.public_send(attributes)
end
move_data = order.exported_attributes[:move].map do |attributes|
move.decorate.public_send(attributes)
end
stop_data = order.exported_attributes[:stop].map do |attributes|
stop.decorate.public_send(attributes)
end
csv << order_data + move_data + stop_data
end
end
end
end
end
Это не хороший код качества ..
Я сделал это вчера:
def to_csv
CSV.generate(headers: true) do |csv|
csv << h.t(self.first.exported_attributes.values.flatten) # headers
self.each do |order|
order.moves.each do |move|
move.stops.each do |stop|
csv << order.exported_attributes[:order].map { |attr| order.public_send(attr) } +
order.exported_attributes[:move].map { |attr| move.decorate.send(attr) } +
order.exported_attributes[:stop].map { |attr| stop.decorate.send(attr) }
end
end
end
end
end
Update:
Спасибо за ответ ниже, до сих пор не может избавиться от вложенные петли, но, по крайней мере, они хорошо структурированы без ключевого значения большого массива :)
def to_csv
CSV.generate(headers: true) do |csv|
csv << h.t(Order.first.decorate.exported_attributes + Move.first.decorate.exported_attributes +
Stop.first.decorate.exported_attributes)
self.each do |order|
order.moves.each do |move|
move.stops.each do |stop|
csv << order.exported_values + move.decorate.exported_values + stop.decorate.exported_values
end
end
end
end
end
с ними в абстрактном классе декоратора:
def exported_attributes
[]
end
def exported_values
exported_attributes.map { |attr| self.public_send(attr) }
end
и в каждом декоратор порядке, двигаться, стоп, я снова пересмотрел exported_attributes.
в рубине, когда у вас есть * одна петля лайнера * рекомендуется использовать ** не ** использовать * делать ..end * цикл, вместо этого использовать * {} *. Пример: 'order_data = order.exported_attributes [: order] .map {| attributes | order.public_send (attributes)} '. Просто сделав это, вы перешли от 3 строк до 1 строки. –
* за исключением случаев, когда один вкладыш длинный и становится (четным) жестким (er), как в приведенном выше примере. – unused
@ user181452 Вы можете предоставить некоторые данные образца? Трудно догадаться, в чем цель начала, переместить вещи наверху. – unused