I posted something similar with this, but I found some code that I thought would work, tried it and it did not work. What I am trying to do is limit the number of questions being displayed in an application loading an XML file externally. The XML file has 50 questions, and I want to randomly display 35 questions.
Here is the code
package exam {
import flash.net.* //to create URLRequest and load XML file
import flash.events.* //for Load events
//import flash.display.* //for testing purposes - remove when testing complete
//This class downloads the XML document, and then inserts info into arrays and variables.
//Also provides text of questions and correct answers when requested.
internal class XaMLDiplomat extends EventDispatcher {
//VARIABLES:
//for loaded XML doc
private var myXML:XML;
//for loading in XML
private var examLoader:URLLoader;
private var numQstns:Number; //count of total questions in a section
private var sectStart:Number;
//contains exam questions - ALL ARRAYS ARE ZERO RELATIVE -> actual question numbers = array index + 1
private var questions:Array;
//contain associated answer choices
private var choiceA:Array;
private var choiceB:Array;
private var choiceC:Array;
private var choiceD:Array;
private var choiceE:Array;
private var choiceF:Array;
//array of the correct answers
private var answers:Array;
//use custom Mixer class to randomize order
private var myMixer:Mixer;
//CONSTRUCTOR
public function XaMLDiplomat () { //NEED TO ADD ARGUMENTS (docLocation)
//create URLRequest from argument
var examSite:URLRequest = new URLRequest("protected/exam.xml");
//create a loader for the XML
examLoader = new URLLoader();
//add listener for load completion
examLoader.addEventListener(Event.COMPLETE, fullyLoaded);
examLoader.load(examSite);
//var ugly:Mixer = new Mixer(25);
}
//Load listener - creates XML object, and checks it for multiple sections. If multiple, it asks users
//which section they want - FIRST it needs to check database for any completed sections.
//If single, it goes ahead and starts array creation for first (& only) section
private function fullyLoaded (e:Event):void {
myXML = new XML(examLoader.data);
//myXML.prettyPrinting = false;
//still need to pull out SYSTEM data and pass it along...
var system:XMLList = myXML..SYSTEM;
var sysObj:Object = new Object();
sysObj.examTitle = system.TITLE.toString();
sysObj.totalMin = system.MINUTES.toString();
sysObj.retakePW = system.RETAKEPW.toString();
var numSections:Number = myXML..SECTION.length();
if (numSections == 1) {
generateArrays(1);
}
dispatchEvent(new MultiSectEvent(MultiSectEvent.SECTIONS, numSections, sysObj));
}
//Assigns arrays to instance variables for the selected section
internal function generateArrays (sectn:Number):void {
var whichSection:XMLList = myXML..SECTION.(@id == String(sectn));
var probList:XMLList = whichSection.PROBLEM;
numQstns = probList.length();
sectStart = Number(probList[0].@id);
questions = new Array();
choiceA = new Array();
choiceB = new Array();
choiceC = new Array();
choiceD = new Array();
choiceE = new Array();
choiceF = new Array();
answers = new Array();
for (var i:Number=0; i<numQstns; i++) {
var curProb:XMLList = probList.(@id == String(i+1));
if (curProb.QUESTION.hasSimpleContent()) {
questions* = curProb.QUESTION.toString();
}else {
//trace(curProb.QUESTION.toXMLString());
questions* = dropTags(curProb.QUESTION[0]);
}
choiceA* = curProb.CHOICE.(@letter == "a").toString();
choiceB* = curProb.CHOICE.(@letter == "b").toString();
choiceC* = curProb.CHOICE.(@letter == "c").toString();
choiceD* = curProb.CHOICE.(@letter == "d").toString();
choiceE* = curProb.CHOICE.(@letter == "e").toString();
choiceF* = curProb.CHOICE.(@letter == "f").toString();
answers* = curProb.CHOICE.(hasOwnProperty("@correct") && @correct == "true").@letter.toString();
}
myMixer = new Mixer(numQstns);
/*
trace("Question: "+questions[3]);
trace("a: "+choiceA[3]);
trace("b: "+choiceB[3]);
trace("c: "+choiceC[3]);
trace("d: "+choiceD[3]);
trace("
answer: "+answers[3]); */
}
public function shuffle (a:Array,i:int):Array {
var rndm:int;
var b:Array = a.slice();
var c:Array = [];
while (i) {
rndm = Math.random() * b.length;
c.push(b.splice(rndm,1)[0]);
i--;
}
return c;
}
var randomPool:Array = shuffle(questions,35);
//method for external classes to acquire text of current exam question
internal function getQuestion (qnum:Number):Object {
var returnObj:Object = new Object();
var randomQ:Number = myMixer.getRandomNumber(qnum-1);
returnObj.q = questions[randomQ];
returnObj.ca = choiceA[randomQ];
returnObj.cb = choiceB[randomQ];
returnObj.cc = choiceC[randomQ];
returnObj.cd = choiceD[randomQ];
returnObj.ce = choiceE[randomQ];
returnObj.cf = choiceF[randomQ];
returnObj.num = qnum;
//trace(randomQ);
return returnObj;
}
private function dropTags (txt:XML):String {
var txtString:String = "";
for each (var child:XML in txt.*) {
if (child.nodeKind == "text") {
txtString += child.toString();
}else {
txtString += " " + child.toXMLString();
}
}
//trace(txtString);
return txtString;
}
/*
private function dropTags (txt:String):String {
var sliceStart:Number = txt.indexOf(">");
var sliceStop:Number = txt.lastIndexOf("<");
return txt.slice((sliceStart+1), sliceStop);
}*/
internal function getAnswer (num:Number):String {
return answers[num];
}
internal function getQCount ():Number {
return numQstns;
//trace (numQstns);
}
internal function getSectStart():Number {
return sectStart;
}
internal function getRealNum (num:Number):Number {
return myMixer.getRandomNumber(num-1);
}
}
}
The specific code I am using to try and limit the display is this.
public function shuffle (a:Array,i:int):Array {
var rndm:int;
var b:Array = a.slice();
var c:Array = [];
while (i) {
rndm = Math.random() * b.length;
c.push(b.splice(rndm,1)[0]);
i--;
}
return c;
}
var randomPool:Array = shuffle(questions,35);
more or less what I think I need to do is compile the set of questions into a new array without randomizing or shuffling, then copy the array into a temp array and shuffle. Then run a for loop on the temp array with a maximum count of 35 and store each question into a new array.