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 ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.