Javascript如何从Math.random中获取唯一值。我怎么能让它停止重复?

时间:2017-11-13 18:49:34

标签: javascript arrays unique

我试图通过jquery / javascript从某个网站远程获取一些HTML dom元素。这些元素在数组中是唯一的,但是当我尝试使用math.random()*我的array.length打印它们时,我看到重复。我希望imgIdx是独一无二的。

所以为了帮助我学习,有人可以帮我确定我在这里缺少什么吗?

myarray = [
{ thumb : "http://url.com/img1.jpg", big : "http://url.com/img51.jpg" },
{ thumb : "http://url.com/img61.jpg", big : "http://url.com/img671.jpg" },
{ thumb : "http://url.com/img666.jpg", big : "http://url.com/img371.jpg" },]

function addSomeImages(limit) {
    for (var i = lastIdx; i < lastIdx + limit; i++) {
        var imgIdx = Math.floor(Math.random() * myarray.length);
        $('#endless-gallery').append('<a data-fancybox="gallery" href="' + myarray[imgIdx].big + '">' + '<img class=photo src="' + myarray[imgIdx].thumb + '' +
            '" />' +
            '</a>');
    }

1 个答案:

答案 0 :(得分:0)

重要的是要注意,我已经注意到的是,为什么您当前的解决方案无法正常工作,或者为什么改组您的阵列是理想的方法。您需要意识到的是,您当前的代码只是生成一个随机索引,供您用于访问数组中的元素。就像滚动模具一样,你重新滚动一个数字的可能性要大于滚动每个数字而不重复的数字。这是(伪)随机数生成的全部要点,结果实际上是非确定性的。

考虑到这一点,为了从数组中随机检索元素而不重复,您必须找到一种通过设计排除重复的方法。最实际的两种方法是:

1)对数组进行随机播放,只需按照问题评论中的说明进行迭代,或者

2)从数组中删除被访问的元素并循环,直到数组为空。

在上面两个中,简单地改组阵列更加实用,并且不会导致阵列的破坏(或者需要克隆阵列并破坏克隆),所以它很容易理想解决方案供您使用。

为什么这些工作在您的原始解决方案没有:

时有效

对数组进行混洗是一个过程,通过该过程,您的数组包含与最初包含的元素完全相同的元素,但只是在数组中随机排序。就像名字所暗示的那样,它就像洗牌一样;你总会拥有标准的52张独特牌,但他们只是处于不同的顺序。当您浏览洗牌时,不会有任何风险以某种方式遇到您已经通过的同一张卡。

移除一个元素并循环直到空,就像是一张完美分类的52张独特卡牌,并从牌组中随机抽出一张,丢弃你已经拉出的牌。如果您拔出的卡片不再在卡片中,您将永远不会有将同一张卡片拉出来的风险。

你现在正在做什么,拿着那张完美分类的52张牌,看着一张随机牌,并在重复这个过程之前把它放回到牌组里面。该卡仍在那里,因为您只是在查看随机卡片,您可能会无意中再次看到它。

由于对数组进行混洗然后迭代结果通常是理想的方法,请考虑使用评论中提到的F​​isher-Yates shuffle函数:

function shuffle(array) {
    var currentIndex = array.length, temporaryValue, randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {

        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }

    return array;
}

然后你可以做类似的事情:

myarray = [ ... ];
myarray = shuffle(myarray);

function addSomeImages(limit) {
    //note: ensure that "lastIdx + limit <= myarray.length" or you could exceed the array bounds!
    for (var i = lastIdx; i < lastIdx + limit; i++) {
        $('#endless-gallery').append('<a data-fancybox="gallery" href="' + myarray[i].big + '"><img class="photo" src="' + myarray[i].thumb + '" /></a>');
    }
}