Reputation: 1521
I'm trying to create random test answers. Using a unique ID (Text) - Below randomizes the list only once when I use it. If I reload page it doesn't randomize again.
Also - if it is a True False Answer of only 2 choices. It doesn't work.
Any thoughts folks? Or is there an easier way to do this. I know I can do it with numbers easily, but I have a preference for unique answer ID in text)
<cfset strList = "rttt,ddde,ffss,gggd" /> - works only once
<cfset strList = "True,False" /> - doesn't work
<!---
Create a struct to hold the list of selected numbers. Because
structs are indexed by key, it will allow us to not select
duplicate values.
--->
<cfset objSelections = {} />
<!--- Now, all we have to do is pick random numbers until our
struct count is the desired size (4 in this demo).
--->
<cfloop condition="(StructCount( objSelections ) LT 4)">
<!--- Select a random list index. --->
<cfset intIndex = RandRange( 1, ListLen( strList ) ) />
<!---
Add the random item to our collection. If we have
already picked this number, then it will simply
overwrite the previous and the StructCount() will
not be changed.
--->
<cfset objSelections[ ListGetAt( strList, intIndex ) ] = true />
</cfloop>
<cfoutput>
<!--- Output the list collection. --->
<cfset newlist = "#StructKeyList( objSelections )#">
#newlist#
</cfoutput>
Upvotes: 2
Views: 998
Reputation: 4786
If you are looking to return a randomized list of answers, you can use Java Collections to interact with your ColdFusion list (after turning the list into an array).
<cfscript>
// Our original answer list.
strlist1 = "rttt,ddde,ffss,gggd" ;
// Convert our lists to arrays.
answerArray1 = ListToArray(strList1) ;
// Create the Java Collection object.
C = CreateObject( "java", "java.util.Collections" ) ;
// Java shuffle() our array.
C.shuffle(answerArray1) ;
// Output our shuffled array (as an array).
writeDump(answerArray3) ;
// Or convert it to a list for output.
randomAnswerList = ArrayToList(answerArray3) ;
writeoutput(randomAnswerList) ;
</cfscript>
https://trycf.com/gist/3a1157a11154575e705411814d10ea92/acf?theme=monokai
Since you're working with small lists, Java's shuffle()
should be pretty quick. With large lists, I believe it can be much more inefficient than building out a randomizing function to shuffle the list. This works because ColdFusion Arrays are automatically also Java Arrays. CF works very well with Java, especially for these types of manipulations.
Note 1: Java shuffle()
operates directly on its input array, so you are actually changing the array itself.
Note 2: Depending on what you want to do with the list, it may be much easier to leave your shuffled answers in an Array object and work with that. Also, Java Collection.shuffle()
will work with Structs. And are you generating the answer list from a query? This will still work, but depending on how you use the query afterwards, you probably wouldn't want to use shuffle()
directly on the query object.
Upvotes: 1
Reputation: 86
The reason it does not re-randomize your list after a reload is because Structs are not ordered. You are better to use an array or even a java hashtable. If I understand correctly, you are just trying to take a list, and output a re-ordered version of the list? It's probably been answered before in more suscint forms than this, but here is a way, if I have understood your requirement correctly:
<cfset strList = "rttt,ddde,ffss,gggd" />
<cfset newlist = "">
<cfloop condition="ListLen(strList)">
<cfset intIndex = RandRange( 1, ListLen( strList ) ) />
<cfset newlist = ListAppend(newlist, ListGetAt(strList, intIndex))>
<cfset strList = ListDeleteAt(strList, intIndex)>
</cfloop>
<cfoutput>#newlist#</cfoutput>
Upvotes: 0