这是一个doozey。
我有while循环生成一个与之前生成的任何其他随机数不同的随机数。随机数用于从对象中选择文本值。
例如:
quoteArray[1] = "some text"
quoteArray[2] = "some different text"
quoteArray[3] = "text again"
quoteArray[4] = "completely different text"
quoteArray[5] = "ham sandwich"
这是一个较大函数的一部分,在该函数循环通过= quoteArray.length之后,它会重置并重新开始循环。我遇到的问题是以下代码是SOMETIMES产生一个无限循环:
//Note: at this point in the function I have generated a random number once already and stored it in 'randomnumber'
//I use this while statement to evaluate 'randomnumber' until the condition of it NOT being a number that has already been used and NOT being the last number is met.
while(randomnumber === rotationArray[randomnumber] || randomnumber === lastnumber){
randomnumber = Math.floor(Math.random() * (quoteArray.length));
}
当我在console.log(randomnumber)时 - 当我陷入循环时 - 我只是得到'0'。当卡在循环中时,它似乎不像Math.floor(Math.random()*(quoteArray.length))产生一个随机数,而是无限地只是'0'。
谁能告诉我为什么我遇到这个问题?
编辑:这是包含函数+变量声明的完整相关代码
// Function to initialize the quoteObj function quoteObj(text,cname,ccompany,url,height) { this.text=text; this.cname=cname; this.ccompany=ccompany; this.url=url; this.height=height; } // Populate my quotes Object with the quotation information from the XML sheet. var qObj = new quoteObj('','','',''); var quoteArray = new Array(); var counter = 0; //cycles through each XML item and loads the data into an object which is then stored in an array $.ajax({ type: "GET", url: "quotes.xml", dataType: "xml", success: function(xml) { $(xml).find('quote').each(function(){ quoteArray[counter] = new quoteObj('','','',''); console.log(quoteArray[counter]); quoteArray[counter].text = $(this).find('text').text(); quoteArray[counter].cname = $(this).find('customer_name').text(); quoteArray[counter].ccompany = $(this).find('customer_company').text(); quoteArray[counter].url = $(this).find('project').text(); ++counter; }); } }); // This is the setion that is generating my infinite loop issue. // I've included all of the other code in case people are wondering specific things about how an item was initialized, etc. // Generate a random first quote then randomly progress through the entire set and start all over. var randomnumber = Math.floor(Math.random() * (quoteArray.length)); var rotationArray = new Array(quoteArray.length); var v = 0; var lastnumber = -1; bHeight = $('#rightbox').height() + 50; var cHeight = 0; var divtoanim = $('#customerquotes').parent(); //NOT RELATED// // Give the innershadow a height so that overflow hidden works with the quotations. $(divtoanim).css({'height' : bHeight}); // Rotate the Quotations Randomly function. setInterval(function(){ randomnumber = Math.floor(Math.random() * (quoteArray.length)); //checks to see if the function loop needs to start at the beginning. if(v == (quoteArray.length)){ rotationArray.length = 0; v = 0; } //determines if the random number is both different than any other random number generated before and that is is not the same as the last random number while(randomnumber === rotationArray[randomnumber] || randomnumber === lastnumber){ randomnumber = Math.floor(Math.random() * (quoteArray.length)); } lastnumber = randomnumber; rotationArray[randomnumber] = randomnumber; ++v; //NOT RELATED// //animation sequence $('#ctext, #cname').animate({'opacity':'0'},2000, function(){ $('#ctext').html(quoteArray[randomnumber].text); $('#cname').html('- ' + quoteArray[randomnumber].cname); cHeight = $('#customerquotes').height() + 50; adjustHeight(bHeight,cHeight,divtoanim); $('#ctext').delay(500).animate({'opacity':'1'},500); $('#cname').delay(1500).animate({'opacity':'1'},500); }); },15000);
答案 0 :(得分:2)
这是一个异步问题:代码运行时数组quoteArray
为空,因为它会触发ajax请求,并继续。依赖于quoteArray
的任何内容都应位于success
的{{1}}函数内。
当您在控制台中键入$.ajax
时,数组有一个长度,仅因为那时Ajax请求已完成。
答案 1 :(得分:0)
Math.floor(Math.random() * (5));
确保正确找到阵列长度?
答案 2 :(得分:0)
首先,由于您更新了问题,请确保正确处理异步数据。由于ajax调用是异步的,因此一旦调用成功并返回数据,您将需要确保只运行随机数发生器。
其次,假设您正确处理asyc数据,结果集的大小可能太小。因此,您可能经常随机获得相同的数字。然后,你不能使用这个号码,因为你已经这样做了。
您需要做的是每次都从结果数组中弹出已经使用过的部分。重新计算数组长度,然后从中拉出一个随机数。然而,这种感觉随机的可能性很小。
可能有一种更有效的方法可以做到这一点,但这是我的去处:
var results = ['some text','some text2','some text3','some text4','some text5', /* ...etc */ ],
randomable = results;
function getRandomOffset( arr )
{
var offset,
len;
if( arr.length < 1 )
return false;
else if( arr.length > 1 )
offset = Math.floor(Math.random() * arr.length );
else
offset = 0;
arr.splice( offset, 1 );
return [
offset,
arr
];
}
while( res = getRandomOffset( randomable ) )
{
// Set the randomable for next time
randomable = res[1];
// Do something with your resulting index
results[ res[0] ];
}
发送给函数的arr
gument应该是从它返回的数组(第一次除外)。然后根据需要调用该函数,直到它返回false。