[英]How to rewrite this each loop in ruby?
I have this loop: 我有这个循环:
stations = Station.where(...)
stations.all.each do |s|
if s.city_id == city.id
show_stations << s
end
end
This works well, but because of looping the all the data, I think it's kinda slow. 这很好用,但是由于循环所有数据,我认为这有点慢。 I've tried to rewrite it with using
select
, like this: 我尝试使用
select
重写它,如下所示:
show_stations << stations.select { |station| station.city_id == city.id}
But the amount of saved data into show_stations
is different compared to the each
version and then, the data are in different format (array/object). 但是与
each
版本相比,保存到show_stations
数据量有所不同,因此数据的格式(数组/对象)不同。
Is there any better/faster way to rewrite the loop version? 有没有更好/更快的方法来重写循环版本?
The fastest version of this maybe the built-in rails ActiveRecord method for finding associated objects. 最快的版本可能是用于找到关联对象的内置rails ActiveRecord方法。
So provided your Station model contains this: 因此,只要您的Station模型包含以下内容:
class Station < ActiveRecord::Base
belongs_to :city
And your City model contains this: 您的城市模型包含以下内容:
class City < ActiveRecord::Base
has_many :stations
Then rails automatically generates the method city.stations
which automatically fetches the stations which contain that city's id from the database. 然后,rails自动生成方法
city.stations
,该方法自动从数据库中获取包含该城市ID的站点。 It should be pretty optimized. 它应该是相当优化的。
If you want to make it even faster then you can add add_index :stations, :city_id
to your table in a migration and it will retrieve faster. 如果要使其更快,则可以在迁移中将
add_index :stations, :city_id
到表中,它将更快地检索。 Note that this only saves time when you have a lot of stations to search through. 请注意,这仅在您有大量要搜索的电台时才节省时间。
If you need to make it an array you can just convert it after with city.stations.to_a
. 如果需要将其设置为数组,则可以在之后使用
city.stations.to_a
对其进行转换。 And if you wanted to narrow it further, just use the select
method and add the conditions that you wanted to previously add in your Station.where(...)
statement. 并且,如果您想进一步缩小范围,只需使用
select
方法并在Station.where(...)
语句中添加之前要添加的条件。
(eg city.stations.to_a.select { |item| your_filter }
) (例如
city.stations.to_a.select { |item| your_filter }
)
您还应该缓存查询结果,例如
stations ||= Station.where("your where").where(:city_id => city.id)
Station appears to be an active record model. Station似乎是一个活动记录模型。 If that is the case, and you don't need all the stations, you can add the
city.id
filter to your where
statement. 如果是这种情况,并且不需要所有站点,则可以将
city.id
过滤器添加到where
语句中。
The issue you're having now is that you're adding the array returned from select
as the last item of show_stations
. 现在遇到的问题是,您要将
select
返回的数组添加为show_stations
的最后一项。 If you want show_stations
to only contain stations that match city.id
then use show_stations = ...
rather than show_stations << ...
. 如果要让
show_stations
只包含与city.id
匹配的电台, city.id
使用show_stations = ...
而不是show_stations << ...
If you want show_stations
to contain what it already contains plus the stations that match city.id
then use show_stations + stations.select { |station| station.city_id == city.id }
如果希望
show_stations
包含已经包含的内容以及与city.id
匹配的站点, city.id
使用show_stations + stations.select { |station| station.city_id == city.id }
show_stations + stations.select { |station| station.city_id == city.id }
. show_stations + stations.select { |station| station.city_id == city.id }
。 (There are a number of other approaches for adding two arrays together.) (还有许多其他方法可以将两个数组加在一起。)
Maybe you need to include into the where
clause the city parameter: 也许您需要在
where
子句中包含city参数:
stations = Station.where("your where").where(:city_id => city.id)
or the same 或相同
stations = Station.where("your where").where('city_id = ?', city.id)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.