【问题标题】:Exit function and call itself again without returning undefined退出函数并再次调用自身而不返回 undefined
【发布时间】:2016-05-31 20:55:17
【问题描述】:

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

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 &amp;&amp; uniqueIndex == lastIndex) 会导致它返回未定义的索引。所以我试图退出函数并重新调用函数重试的方式并没有按计划工作。

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

【问题讨论】:

    标签: javascript


    【解决方案1】:

    当你没有得到你想要的结果时重新投掷骰子的方法不是最佳的,当随机数不是那么随机时(倾向于重复相同的数字),那么你就不必要地循环了。

    试试这个:

    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);
    

    【讨论】:

    • 这可以只用一个数字吗?因为我不想只传递数字的实际数组,所以在你的例子中,我只想传递它RandEleGenerator(3);
    • @Cameron 你已经有了从数字 3 构造数组 [1, 2, 3] 的代码。for (var i = 0; i &lt; indexes; i++) { listIndexes.push(i); } 你可以在调用 RandEleGenerator 之前执行它,或者你可以在内部执行它,取而代之的是数字 3 作为参数(但我总是会推荐两者中更灵活的一个,在这种情况下是前者)。
    • 你能给我举个例子说明我会怎么做吗,因为我没有听懂你的意思。干杯朋友。
    【解决方案2】:

    试试这个:

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

    【讨论】:

      【解决方案3】:

      只需更改您的空返回以再次运行该函数:

      return getRandomIndex(indexes);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-10
        • 1970-01-01
        • 1970-01-01
        • 2013-11-04
        • 2020-04-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多