JavaScript:我需要一个递归函数来解决这个问题吗?

时间:2011-07-21 01:01:39

标签: javascript

在这个小提琴http://jsfiddle.net/5L8Q8/28/中,如果单击黑色按钮,它会从数组中随机选择两个值(红色或蓝色)中的一个。随机选择的值将分配给ran。在我的实际应用程序中,该数组中将有16个元素。

如果你是粉红色的“playagain”按钮,它会从同一个数组中选择一个随机元素,但我想确保它与上次选择的不一样。

因此,当我点击playagain时,我会将ran分配给lastran并将其与数组中下一个随机选择的值进行比较,如果它们相同,则再次选择。但是,我所拥有的方式并不能保证(在完成playagainran时有所不同。

我想我需要一个递归函数,其中注释2在下面的代码中,但是当我尝试创建它时,我一直在破坏我的代码。

您能否对下面代码中的3条评论发表评论?

注意,我是一个相对新手,所以这段代码可能很糟糕......

$("#playagain").click(function(){
    lastran = ran; 


    ran = getRandom(myArray, true);

    if (ran === lastran) { 

        ran = getRandom(myArray, true); //1. do I need to return this?

           //2. want to test ran === lastran again.. How to set up recursive function?

    } else {

       return; //3.is this the right thing to do here?
    }  

});

5 个答案:

答案 0 :(得分:3)

while( (ran = getRandom(myArray, true)) === lastran)
    ;

是你想要的。声明

ran = getRandom(myArray, true)

不仅会将ran设置为getRandom(),还会返回ran的值。 (这是JavaScript中相当常见的习惯用法,是C语言的延续。)

所以你的完整代码可以是:

$("#playagain").click(function(){
    /*var */lastran = ran; 

    while( (ran = getRandom(myArray, true)) === lastran)
        ;

    // update UI here

});

答案 1 :(得分:2)

您可以使用while循环而不是if。

while(ran == lastran)
{
  ran = getRandom(myArray, true);
}

它会继续尝试,直到它获得不同的值。

答案 2 :(得分:1)

每次运行后,只需从数组中删除“key”,然后将lastran推送到它的末尾。然后更新的getRandom函数如下所示可用于#button和#playagain。 http://jsfiddle.net/ghostoy/5L8Q8/32/

function getRandom(array, getVal) {
    var key = Math.floor(Math.random() * array.length),
        value = array[key];

    if (lastran) {
        array.push(lastran);
    }

    array.splice(key, 1);
    lastran = value;

    if (getVal) {
        return value; 
    }
    return key; 
}

答案 3 :(得分:0)

我认为你的方法并不是解决这个问题的最佳方法。从理论上讲,你可以连续多次获得相同的数字,这使得它成为一个“缓慢”的算法,你使它变得比需要的更复杂。

文本中的另一种方法:

- if no previous element has been picked pick a number between 0 and the number of elements in your array (16) otherwise pick a number between 0 and #elements-1 (15)
- if the chosen element is greater or equal to the last element picked add 1 to it 
- store this index number as the last picked element
- return the array[picked-element]'s value

答案 4 :(得分:0)

你可以让getRandom本身递归:

function getRandom(array, getVal, lastRan) { 
    var key = Math.floor(Math.random() * array.length);
    if ((!getVal && key == lastRan) || (getVal && array[key] == lastRan))
        return getRandom(array, getVal, lastRan);
    return getVal ? array[key] : key;
}

称它传递最后一个随机值:

getRandom(myArray, true, lastran)

它的工作原理如下。您始终将getRandom传递给检索到的最后一个随机值。在第一个条件中,我们检查是否只生成了此值的副本(使用键本身或其在数组中的相应值,具体取决于getVal是否为true)。如果是这样,我们再次返回调用getRandom的结果,再次传递使用的最后一个随机数。这可以根据需要多次发生。

当对getRandom的这些调用之一产生新数字时,第一个条件中的表达式将为false。在这种情况下,我们返回所需的值(通过第二个return语句),并且所有对getRandom的递归调用都是“展开的”。 (请记住,我们在每一步都将getRandom的每次调用的值都返回。)

相关问题