我有一些简单的代码,使用minmax算法来定位鸟类。一切正常但我发现我的编程不好,我相信有更好的解决方案。我在RoR方面没有经验,但如果有人知道更好的方法来实现相同的解决方案,那么我很高兴;)。
我讨厌有两个部分,我必须创建4个列表来确定不同组合的最大值或最小值(min-max算法的核心)和非常丑陋的SQL hack。
谢谢!
def index
# fetch all our birds
@birds = Bird.all
# Loop over the birds
@birds.each do |bird|
@fixed = Node.where("d7type = 'f'")
xminmax = []
xmaxmin = []
yminmax = []
ymaxmin = []
@fixed.each do |fixed|
rss = Log.find_by_sql("SELECT logs.fixed_mac, AVG(logs.blinker_rss) AS avg_rss FROM logs
WHERE logs.blinker_mac = '#{bird.d7_mac}' AND logs.fixed_mac = '#{fixed.d7_mac}' ORDER BY logs.id DESC LIMIT 30")
converted_rss = calculate_distance_rss(rss[0].attributes["avg_rss"])
xminmax.push(fixed.xpos + converted_rss)
xmaxmin.push(fixed.xpos - converted_rss)
yminmax.push(fixed.ypos + converted_rss)
ymaxmin.push(fixed.ypos - converted_rss)
end
pos = {x: (xminmax.min + xmaxmin.max) / 2, y: (yminmax.min + ymaxmin.max) / 2}
puts pos
end
端
答案 0 :(得分:1)
你可以做的两件事是(假设鸟类可能是一张大桌子)改变Bird.all到
Bird.find_each do |bird|
... code ...
end
循环遍历许多表记录是一种更有效的方法。
第二:从每个循环中取出@fixed = Node.where("d7type = 'f'")
,因为它的查询不需要任何变量。把它放在循环上面,这样每次都不会执行。
3rd(不是优化而是更安全的代码):您的Log.find_by_sql
看起来很简单,可以使用active_record,您可以将其更改为:
Log.select('fixed_mac, AVG(logs.blinker_rss) AS avg_rss, blinker_mac').
where(blinker_mac: bird.d7_mac, fixed_mac: fixed.d7_mac).
order('id DESC').limit(30)
converted_rss = calculate_distance_rss(rss.first.avg_rss)
其他一切看起来都不错。