2011-07-05 4 views
0

표 - 연락처 출력하기 '임의'기록

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

어떻게 '무작위',이 테이블에서 넣어 기록을 I을 수행. 정확히 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

무엇을 다른 사람보다 하나 더가있는 경우. 예를 들어 '동료'보다 '친구'가 더 많습니까? –

+0

친구 모델에서 레코드 검색을 중단합니다. –

+0

무작위 순서이므로 완전히 임의의 항목이 아닙니다. –

답변

1

이 점에 대해 어떻게 생각하십니까?

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

이렇게하면 모든 하위 모델에서 하나의 항목을 가져옵니다.

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)

관련 문제