退出函数并再次调用自身而不返回未定义的

时间:2016-02-19 10:14:05

标签: javascript

我有以下函数可以从数组中提取一个随机索引而不重复索引,并继续将它们拉出来直到所有已经使用过,然后重置自己并开始重新使用它们。它还尝试以确保拉出的最后一个与重置时拉出的下一个不同,这样你就不会出现相同的索引。行。

var listIndexes = [];
var lastIndex;

function getRandomIndex(indexes)
{
    if (!listIndexes.length) {
        for (var i = 0; i < indexes; i++) {
            listIndexes.push(i);
        }
    }

    var randomIndex = Math.floor(Math.random() * listIndexes.length);
    var uniqueIndex = listIndexes[randomIndex];

    listIndexes.splice(randomIndex, 1);

    if(lastIndex && uniqueIndex == lastIndex)
    {
        listIndexes = [];
        getRandomIndex(indexes);
        return;
    }

    lastIndex = uniqueIndex;

    return uniqueIndex;
}

var index = getRandomIndex(5);

console.log(index);

然而,当它遇到代码时:if(lastIndex && uniqueIndex == lastIndex)会导致它返回未定义的索引。所以我试图退出该函数并重新调用该函数再试一次的方式并没有按计划进行。

如何退出当前函数调用并重新调用该函数以获取与lastIndex不同的新随机索引。请注意,lastIndex保持不变,直到新索引不相同,无论函数被调用多少次。

3 个答案:

答案 0 :(得分:2)

试试这个:

if(lastIndex && uniqueIndex == lastIndex)
    {
        listIndexes = [];
        return getRandomIndex(indexes);
    }

答案 1 :(得分:1)

只需更改空回车即可再次运行该功能:

return getRandomIndex(indexes);

答案 2 :(得分:1)

当你没有得到你想要的结果时,重新抛出骰子的方法不是最佳的,当随机数不是随机的(往往重复相同的数字)时,你就是&#39;不必要地重新骑行。

试试这个:

function RandEleGenerator(list) {
    var lastChosen;
    var currentList = list.slice();

    function randomIndex() {
        return Math.floor(Math.random() * currentList.length);
    }
    return function() {
        // Choose element
        var index = randomIndex();
        var obj = currentList[index];

        // Remove it from current list
        currentList.splice(index, 1);
        if(currentList.length == 0) {
            // If empty, restore list
            currentList = list.slice();

            // But not without removing last chosen element
            index = currentList.indexOf(obj);
            currentList.splice(index, 1);
        }
        return obj;
    };
}

用法:

var reg = new RandEleGenerator([1,2,3]);
reg();   // 3
reg();   // 2
reg();   // 1
reg();   // 2
reg();   // 3
reg();   // 2
reg();   // 1

所选元素将从列表中删除,因此无法重新选择。为了保证在列表结束时不重复某个值,将重新创建列表,并立即从列表中删除所选的最后一个元素。然后,该过程将继续随机选择要从列表中删除的元素。

修改 为了说明,生成一个数组以传递给RandEleGenerator,下面的代码就足够了:

var arrToPass = [];
for (var i = 0; i < 3; i++) {
    arrToPass.push(i);
}
var reg = new RandEleGenerator(arrToPass);