2011-07-05 7 views
0

表を出力する - コンタクトは「ランダム」の記録に

Name  Channel 
Teejay Friends 
John  Colleagues 
Rick  Friends 
Carl  Business 
Vulcan Business 
Scott Office 
Alex  Friends 

どのように「ランダム」この表から、私はアウトプット行うレコード、。まあ、正確にはrandomではありません。同じChannelのレコードが存在しないレコードを出力できるはずです。

A record in the `Friends` Channel 
A record in the `Colleagues` Channel 
A record in the `Business` Channel 
A record in the `Office` Channel 
A record in the `Friends` Channel 
A record in the `Business` Channel 
A record in the `Friends` Channel 

詳細:

フレンドモデル、同僚モデル、ビジネスモデル、オフィスモデルは、連絡先の子モデルです。

+0

他よりも1からより多くがある場合はどのような。たとえば、「友人」よりも「友人」の方が多いでしょうか? –

+0

これは、友人モデルからのレコードの取得を停止します。 –

+0

ですので、ランダムな順序であり、完全にランダムではありません –

答えて

1

あなたはこれについてどう思いますか?

[ Friend, Colleague, Business, Office ].each do |klass| 
    klass.find(:first, :offset => (klass.count * rand).to_i, :limit => 1) 
end 

これは、すべての子モデルから1つのエントリをフェッチします。これは非常に高速であってもよいが、作品ではないでしょう:)

あなたは2回の繰り返しが必要な場合に、あなたはブロック全体をラップすることができます。

2.times do 
end 

しかし、モデルのその順番を意識するが、ここで固定されています。 。

prev = nil 
10.times do 
    klass = [ Friend, Colleague, Business, Office ].reject { |k| k == prev }.shuffle.first 
    p klass.find(:first, :offset => (klass.count * rand).to_i, :limit => 1) 
    prev = klass 
end 

更新:あなたは、ランダムにも必要な場合は好奇心のために

を私はそのための小さな方法を作りました。 SQLiteを使用している場合は、RAND()RANDOM()に置き換える必要があることに注意してください。また、this questionも確認してください。

def get_random_items(classes, count) 
    # collect at least count/2 random items from each class 
    items = Hash.new do |hash,klass| 
    hash[klass] = klass.find(:all, :order => "RAND()", :limit => (count.to_f/2).ceil) 
    end 

    results = [] 
    prev = nil 

    while (classes.length > 0 && results.length < count) do 
    klass = classes.shuffle!.pop 

    item = items[klass].pop 
    next unless item 

    classes << prev if prev 
    prev = (items[klass].length > 0) ? klass : nil 
    results << item 
    end 

    results 

end 

使用法:get_random_items([ Friend, Colleague, Business, Office ], 10)