for example, I am having 10 questions in my DB for that each question has a unique question id
If I enter 5 then 5 question id should be come randomly help me out on this
Discussion posts and replies are publicly visible
My quick solution is to fetch all the IDs from DB, then randomly remove items until only 5 are left.
a!localVariables( local!dbIds: {3,7,42,6,9,13,123,45,889,657}, reduce( rule!TST_RemoveRandomItemFromList(_,_), local!dbIds, enumerate(5) ) ) TST_RemoveRandomItemFromList( list(Integer Array), dummy(Integer) remove( ri!list, ceiling(rand() * count(ri!list)) )
An alternative would be to fetch all of the questions form the DB (agnostic of their database ids), and then generate a random list of 5 integers in the range of the size of the fetched array (ensuring no duplicate random integers are generated) and then use those to index your fetched array.
This may create the same value multiple times. That was my first idea as well and I had no good idea to remove duplicates. I know that union does that, but then I would have to create more than 5 random numbers. But how much? With enough bad luck, all numbers are the same ...
I tried out a nested loop, where the inner loop generates 5 random integers, and the out loop calls that 10k times. I then flattened the list of arrays and performed a union() on them, The underlying generated list is large enough to reduce the risk of ending up with a list of 4 or less unique integers, but very, very unlikely:
a!localVariables( /* local!questions here is the array of quiestions that you'd fetch from the DB*/ local!questions: a!forEach( items: fn!enumerate(10) + 1, expression: "Q" & fv!item ), /* this is where the actual code starts*/ local!randomNumbers: fn!union( tointeger( a!flatten( a!forEach( items: fn!enumerate(10000), expression: a!forEach( items: fn!enumerate(5) + 1, expression: fn!ceiling(fn!rand() * 10, 1) ) ) ) ), tointeger({}) )[{ 1, 2, 3, 4, 5 }], local!questions[local!randomNumbers] )