2016-05-21 2 views
0

У меня есть неизвестное количество категорий.Повторите попытку сбора

Я хочу выбрать одно сообщение из каждой категории, а когда нет больше категорий, я хочу начать с самого начала, пока не доберусь до фиксированных номеров.

Это то, что у меня есть, как я мог повторить эту итерацию до тех пор, пока у меня не будет желаемого количества сообщений?

desired_amount = 40 
categories.each_with_index do |category, index| 
    post = category.posts.order(position: :asc)[index] 
    # do something with the post 
    return if desired_amount == (index + 1) 
end 

ответ

1

Лично я предпочел бы что-то вроде этого:

posts = categories.cycle.take(desired_amount).each_with_index.map do |cat,ind| 
    cat.posts.order(position: :asc)[ind/categories.count] 
end 

Это даст вам первый пост в каждой категории, за которой следует вторая должность в каждой категории и т. д., пока у вас не будет количества должностей, которые вы хотели. Одно из предостережений заключается в том, что если в какой-либо категории не было достаточно сообщений, ваш последний массив имел бы в нем несколько пустых мест (т. Е. Nils).

0

Возможно, попробуйте что-нибудь подобное?

all_posts = [] 
#include posts to prevent constant querying the db 
categories_with_posts = categories.includes(:posts) 

until all_posts.size == 40 
categories_with_posts.each do |category| 
    #pick a random post from current category posts 
    post = category.posts.order(position: :asc).sample 

    # add the post to collection if post is not nil 
    all_posts << post if post 

    # do something with the post 
    break if all_posts.size == 40 
end 
end 
0

Вы можете определить массив пост перед началом цикла:

desired_amount = 40 
posts_array = [] 
unless posts_array.count == desired_amount 
    categories.each_with_index do |category, index| 
    post = category.posts.order(position: :asc)[index] 
    posts_array << post 
    return if desired_amount == (index + 1) 
    end 
end 
Смежные вопросы