Ich bin neu in Ruby, und ich muss Informationen in CSV exportieren. Ich habe diesen Code geschrieben und ich mag ihn nicht wirklich. Ich weiß nicht, wie ich es umgestalten und die verschachtelten Schleifen loswerden kann.Refactoring verschachtelte Schleifen in einer Ruby-Methode, die nach CSV exportiert
Meine Beziehungen sind die folgenden: Reihenfolge hat viele Züge, Bewegung hat viele Stopps.
Ich muss alles in CSV exportieren, also werde ich mehrere Zeilen für die gleiche Reihenfolge haben!
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
Es ist nicht von guter Qualität Code ..
Ich tat dies gestern:
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:
Danke für die Antwort unten, kann immer noch nicht von der loswerden Nested Loops, aber zumindest ist es gut strukturiert ohne Schlüsselwert großes Array :)
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
mit diesem in der abstrakten Dekorateur Klasse:
def exported_attributes
[]
end
def exported_values
exported_attributes.map { |attr| self.public_send(attr) }
end
und in jedem Dekorateur der Ordnung, verschieben, stoppen, ich neu definiert wieder exported_attributes.
in Ruby, wenn Sie eine * ein Liner Loop * haben, wird empfohlen, ** nicht ** zu verwenden * do ..end * cycle, stattdessen verwenden Sie * {} *. Beispiel: 'order_data = order.exported_attributes [: order] .map {| attributes | order.public_send (Attribute)} '. Nur so ging es von 3 Zeilen zu 1 Zeile. –
* außer wenn der Einzeiler lang ist und (sogar) hart (er) wird, wie im obigen Beispiel zu lesen. – unused
@ user181452 können Sie einige Beispieldaten bereitstellen? Es ist schwer zu erraten, was der Zweck des Starts ist, Dinge darüber zu bewegen. – unused