0

In my Rails 4 app, I have submitted Questions. What I want to do is to shuffle the order of the Questions, divide the list into seven (for the next seven days), and then save these Questions with a publish_date.

The publish_dates would be the next 7 days (i.e. Date.current+1, Date.current+2, Date.current+3, Date.current+4, Date.current+5, Date.current+6, Date.current+7).

I understand that I can shuffle the records with @questions.shuffle, but I don't know how to divide the results by seven (I know that since the number of Questions won't always be divisible by 7, some days may end up with one additional Question), and how to assign those to a publish_date.

Thank you in advance for any help!


UPDATE

It sounds like I just need to use in_groups_of to divide the results. What I don't understand now is how to assign the groups to the dates.

yellowreign
  • 3,528
  • 8
  • 43
  • 80
  • 1
    Possible duplicate of [How to split (chunk) a Ruby array into parts of X elements?](http://stackoverflow.com/questions/2699584/how-to-split-chunk-a-ruby-array-into-parts-of-x-elements) – Brad Werth Feb 15 '17 at 04:45
  • Thanks @BradWerth. It sounds like I can use in_groups_of. What I don't understand now, is how to assign those groups to dates. – yellowreign Feb 15 '17 at 04:48
  • I'm sorry, I picked the wrong one, you probably want http://stackoverflow.com/questions/3864139/need-to-split-arrays-to-sub-arrays-of-specified-size-in-ruby – Brad Werth Feb 15 '17 at 04:51

2 Answers2

0

You already figured out how to get your groups. To set the publish date for the group elements, you can do something like this:

questions.map.with_index(1) do |question, i|
  question.update(publish_date: Date.current + i
end

This is assuming that questions are an AR model and publish_date is an actual attribute.

Michael Kohl
  • 66,324
  • 14
  • 138
  • 158
  • Thanks! Yes, `Questions` is an AR model and `publish_date` is an actual attribute. I must've did something wrong. I did `@questions.shuffle`, `@questions.in_groups_of(3)` and then `@questions.map.with_index(1) do |question, i| question.update(publish_date: Date.current + i) end` but all of the `questions` just ended up with Date.current + i (tomorrow) as the publish_date. What did I do wrong? – yellowreign Feb 15 '17 at 05:13
  • Sorry, I realized that I might need to change the number after `with_index` to `(7)`. When I did that, the `publish_date` was different for the `questions`, but it seem to not take into consideration the groups. I selected 9 `questions`, but instead of just assigning them to the next 7 days, it assigned to the next 9 days. I must be missing something between @questions.in_groups_of(3) and your code, but I'm unsure what. – yellowreign Feb 15 '17 at 05:31
  • `@questions.in_groups_of(3)` gives you an array of 3 element arrays. So you need to iterate over the groups. I.e. something like `@questions.in_groups_of(3).each { |group| group.map.with_index... }` – Michael Kohl Feb 15 '17 at 05:52
0

Since you're shuffling the records you don't have to worry about which order they're in. Just deal them out until your stack of questions is exhausted:

# Represent questions here as numbers
questions = (1..15).to_a

# Create an array to collect answers for each day of the week
days = Array.new(7) { [ ] }

# Deal out each of the questions to a day of the week
questions.each_with_index do |q, i|
  days[i % 7] << q
end

# Scramble things just to introduce a bit of variety
days.shuffle!

days
# => [[3, 10], [4, 11], [2, 9], [1, 8, 15], [6, 13], [5, 12], [7, 14]]

This way you'll get a fairly even mix of questions across the given days but without them all being front-loaded on the beginning of the week if there's a non multiple of seven number of them.

I don't think this is possible to do with things like each_slice since the number of questions each day will vary.

tadman
  • 208,517
  • 23
  • 234
  • 262