2013-03-15 49 views
0

我已经在铁轨下面的代码从列表中拾取随机项目,而不重复

@related = [] 
while @related.compact.size < 3 
    @tag = @car.tag_list.sample #pick a tag from the @car's tag_list 
    @sametags = Car.tagged_with(@tag) # get all cars with that tag 
    @related.push((@sametags - Array(@car) - @related.compact).sample) #put that car in @related 
    @counter = @counter + 1 #increment 
    break if @counter == 10 #stop if its taking too long 
end 

我深知这个代码是非常低效的,但我的红宝石扒不为它尚未...

基本上我需要做的就是用3个带有相似标签的汽车模型随机填充@related,这样他们就不会重复。

回答

1

您可以使用随机排序来执行此操作。

@related = Car.limit(3).order('rand()').tagged_with('blood red') 

UPDATE:无@car

@tag = @car.tag_list.sample 
@related = Car.where('id != ?', @car.id).limit(3).order('rand()').tagged_with(@tag) 

UPDATE:如果你正在使用acts_as_taggable_on

@related = Car.where('id != ?', @car.id).limit(3).order('rand()') 
    .tagged_with(@car.tag_list, any: true) 
+0

但这也可能选择@car本身 – 2013-03-15 13:57:13

+0

试试我更新的答案。它基本上不包括'@ car'。并且也使用汽车的所有标签列表:) – jvnill 2013-03-15 13:59:56

+1

'order('rand()')'不是交叉DB,IIRC。 – 2013-03-15 14:02:33

-1

使用争抢第一洗牌数组,然后随便挑顶三个项目。

[1,2,3,4].scramble => [3,1,2,4] 
+0

你可以发布一个链接到'Array#scramble'方法的文档吗? – 2013-03-15 13:58:16

2

Array#sample接受一个数字,大小的样本。所以我认为,你的代码可以简化为:

@tag = @car.tag_list.sample 
@sametags = Car.tagged_with(@tag) 
@related = (@sametags - [@car]).sample(3)