-->

Getting a random venue using actionscript with no

2019-09-08 15:29发布

问题:

Hi users of stack overflow I am currently struggling with randomizing my data via as3 and xml.

I can load in the xml fine and generate a random venue however when I click on the random button I have created, the same node is shown twice! Basically I just want to randomly select data with no repeat of the previous venue if this makes sense.

My xml:

<gallery>
<venue>
        <name>1</name>
        <description>1</description>
        <picture>images/1.jpg</picture>
        <thumb>thumbs/1.jpg</thumb>
        <address>1</address>
        <website>http://1.co.uk</website>
</venue>

<venue>
        <name>2</name>
        <description>2</description>
        <picture>images/2.jpg</picture>
        <thumb>thumbs/2.jpg</thumb>
        <address>2</address>
        <website>http://2.co.uk</website>
</venue>

<venue>
        <name>3</name>
        <description>3</description>
        <picture>images/3.jpg</picture>
        <thumb>thumbs/3.jpg</thumb>
        <address>3</address>
        <website>http://3.co.uk</website>
</venue>
</gallery>

My current code:

var xml:XML = <venues>
<venue name="" description="" address="" website="" picture=""/>
<venue name="" description="" address="" website="" picture=""/> 
<venue name="" description="" address="" website="" picture=""/>
<venue name="" description="" address="" website="" picture=""/>
</venues>;

var Gallerylist:XMLList = new XMLList(xml.venue);

function RandomGallery(e:Event)
{
    var rand:int = Gallerylist.length() * Math.random();
    myTextBoxTitle.text = myXML.venue.name[rand]
    myTextBoxDes.text = myXML.venue.description[rand]
    myTextBoxAddress.text = myXML.venue.address[rand]
    myTextBoxWeb.text = myXML.venue.website[rand]
    myVenueImage.source = myXML.venue.picture[rand]
}
randomBTN.addEventListener(MouseEvent.MOUSE_DOWN, RandomGallery);

回答1:

Create an array with all the names of the venues. You can do this programmatically if the data set gets too large or just start out with hard coded values for your example to get it to work. When you click the random button, pop the name off and use it to pick the next one. This will avoid having to check to see which ones have already been used and you just have to pick from the ones remaining in the array that haven't been viewed. When the user selects the last one and the array is empty, reinitialize it and continue.



回答2:

If you don't mind to shuffle directly your xml to avoid making a new copy of the name you can use a shuffle function like the FicherYates to shuffle in place your data.

You can make an all in one function that will pickup each time it is clicked a new venue and when the end is reached restart over.

here an example of function that will pick a random element each time it responds to the click event:

var xml:XML = <venues>
<venue name="" description="" address="" website="" picture=""/>
<venue name="" description="" address="" website="" picture=""/> 
<venue name="" description="" address="" website="" picture=""/>
<venue name="" description="" address="" website="" picture=""/>
</venues>;


var fnShuffle:Function = function(xl:XMLList):Function {
 var len:int=xl.length();
 var lastUsedIndex:int;

 return function(e:MouseEvent):void{
   var i:int;

   if (len<=0) {
     // restart over since you have reached the end of the list
     len = xl.length();
     i = int(Math.random() * (len--));

     // in case of a new round you don't want to redisplay the last one again
     if (i == lastUsedIndex) i = len; 
   } else {
     i = int(Math.random() * (len--));
   }

   var myRandomVenue:XML = xl[i];
   var tmp:XML = xl[len];
   xl[i] = tmp;
   xl[len] = myRandomVenue;
   lastUsedIndex = len;

   // here do what you want with your randow venue
   trace(myRandomVenue);
 }
}

this.addEventListener(MouseEvent.CLICK, fnShuffle(xml.venue));

You can see it in live at wonderfl each time you click on the TextArea : http://wonderfl.net/c/aQ1D