0

I have set of questions with question types as ["A", "B", "C", "D", "E", "F"], now i need to generate a game specific sets of questions ( 32 questions ) in a defined order

like for game 1 ["A", "A", "C", "A", "D", "A", "C", "D", "A", "A", "E", "F", .. ]

so far i have done following

def self.generate_rps_question(game_id)
    questions = []
    q1 = Question.where(game_id: game_id).where(qtype: "A").sample(1)
    questions << q1 unless questions.include? (q1)
    q2 = Question.where(game_id: game_id).where(qtype: "A").sample(1)
    questions << q2 unless questions.include? (q2)
    q3 = Question.where(game_id: game_id).where(qtype: "C").sample(1)
    questions << q3 unless questions.include? (q3)
    q4 = Question.where(game_id: game_id).where(qtype: "A").sample(1)
    questions << q4 unless questions.include? (q4)
    q5 = Question.where(game_id: game_id).where(qtype: "D").sample(1)
    questions << q5 unless questions.include? (q5)
    .
    .
    .
    .
    questions
end

Is there a better (shorter) way to do this ?

Update

def self.generate_rps_question(game_id, types)
    types.inject([]) do |memo, type|
      unless type == "F"
        while memo.include?(
            q = Question.where(game_id: game_id, qtype: type).sample)  do end # skip unless unique
      else
        q = Question.where(game_id: game_id, qtype: type).sample
      end
      memo << q
    end

  end
2
  • Do want to select questions from a predefined order of question types or do you need to randomize the order of question types as well? Commented Mar 29, 2016 at 5:21
  • @RohitJangid the order of question type is predefined. Commented Mar 29, 2016 at 5:25

1 Answer 1

2

Your approach is not quite correct: whether you encounter already added question, the respective position will be skipped, rather than retried.

def self.generate_rps_question(game_id, types)
  types.inject([]) do |memo, type|
    while memo.include?(
      q = Question.where(game_id: game_id, qtype: type)
                  .sample) do end # skip unless unique
    memo << q
  end
end

The above might be called as

self.generate_rps_question(1, %w[A A C F A D E...])

To include F only once, one probably should filter input to have only one F, If for some weird reason, this check should be done inside a loop, one could do:

def self.generate_rps_question(game_id, types)
  types.inject([]) do |memo, type|
    next memo if memo.include?('F') && type == 'F' # skip superfluous Fs
    while memo.include?(
      q = Question.where(game_id: game_id, qtype: type)
                  .sample) do end # skip unless unique
    memo << q
  end
end
Sign up to request clarification or add additional context in comments.

2 Comments

You could replace types.length.times.inject([]) do |memo, i| by types.inject([]) do |memo, type| to avoid the index access on the types array.
Thanks ! @mudasobwa but what if i don't need type "F" question to be unique ? types.inject([]) do |memo, type| unless type == "F" while memo.include?( q = Question.where(game_id: game_id, qtype: type).sample) do end # skip unless unique else q = Question.where(game_id: game_id, qtype: type).sample end memo << q end can you refactor this too ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.