2013-03-15 52 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)