如何避免在 Math.random() 中生成连续相同的两个数字

3

我正在通过学习YouTube制作报价展示网站。我对一个问题很好奇。当我按下按钮时,它会多次显示相同的报价,但有时并不总是这样(我使用Math.random()函数,所以通常会出现这种情况)。我希望当我按下按钮时,它会更改报价,而不是停留在同一报价上。

我没有任何想法,所以我什么也没做。

const quotes = [
    {
        author: 'Ramiz Karaeski',
        quote: 'Meyvayı soymadan içinden ne çıkacak bilemem, kardeş.'
    },
    {
        author: 'Franz Kafka',
        quote: 'Beyinlerimiz savaşsın isterdim ama görüyorum ki silahsınız bayım.'
    },
    {
        author: 'Fyodor Dostoyevski',
        quote: 'Cehennem nedir? Sevginin artık imkansız olduğuna dair çekilen bir acıdır.'
    },
    {
        author: 'Lev Tolstoy',
        quote: 'Herkes dünyayı değiştirmeyi düşünür, ama kimse kendini değiştirmeyi düşünmez.'
    },
    {
        author: 'Charles Bukowski',
        quote: 'İnsan her zaman ihanet eder sonunda. Kimseye güvenme.'
    },
    {
        author: 'Friedrich Nietzsche',
        quote: 'Oysa güzelliğin sesi kısıktır konuşurken; sadece en uyanık ruhlara yanaşır.'
    },
    {
        author: 'Sabahattin Ali',
        quote: 'On beş günlük ömrü on beş seneye sığdıramazsın da, on beş senelik ömrü on beş günde yaşayıverirsin!'
    }
]

const quoteAuthor = document.getElementById('author');
const displayQuote = document.getElementById('quote');
const buttonChange = document.getElementById('button-change-quote');

buttonChange.addEventListener('click', change);


let random = 0;
change();

function change() {
    random = Math.floor(Math.random() * quotes.length);
    quoteAuthor.innerHTML = quotes[random].author;
    displayQuote.innerHTML = quotes[random].quote;
}

8
将对 Math.random() 的调用放在一个 while 循环中,并不断尝试直到获得一个不同的值。 - Pointy
1
另一种替代方案是暂时移除选定的元素,然后在选择新元素后将其添加回来。 - Tyler Roper
2
使用随机数来生成,而不是选择,但距离上一个选择的数字减少一。这样就不需要浪费地丢弃随机数了。 - aligur
@aligur 请将其添加为答案。这很简单、优雅。 - Jim Mischel
这个任务通常是通过首先正确地 洗牌数组,然后逐个消耗项目来完成的。 - Redu
7个回答

7
你需要使用 do-while 循环,并不断生成新的随机数,直到它与之前的不同。
let random = 0;
change();

function change() {
    let newRandom;
    do{
       newRandom = Math.floor(Math.random() * quotes.length);
    }
    while(newRandom === random)
    random = newRandom
    quoteAuthor.innerHTML = quotes[random].author;
    displayQuote.innerHTML = quotes[random].quote;
}

2
在您的代码中引入另一个变量。
let random = 0;
let last_random = 0;
change();

function change() {
   random = Math.floor(Math.random() * quotes.length);

   if(random != last_random){
      last_random = random;
      quoteAuthor.innerHTML = quotes[random].author;
      displayQuote.innerHTML = quotes[random].quote;
   }else{
     change();
   }
}

1
我个人不太喜欢使用循环。对我来说,“一直尝试直到成功”这种想法感觉有些不够优雅。
另一个我可能会用的替代方法是,从数组中简单地删除先前选择的项并将其存储在变量(prev)中。然后,从剩余选项中选择随机项。

const quotes = [ { author: 'Ramiz Karaeski', quote: 'Meyvayı soymadan içinden ne çıkacak bilemem, kardeş.' }, { author: 'Franz Kafka', quote: 'Beyinlerimiz savaşsın isterdim ama görüyorum ki silahsınız bayım.' }, { author: 'Fyodor Dostoyevski', quote: 'Cehennem nedir? Sevginin artık imkansız olduğuna dair çekilen bir acıdır.' }, { author: 'Lev Tolstoy', quote: 'Herkes dünyayı değiştirmeyi düşünür, ama kimse kendini değiştirmeyi düşünmez.' }, { author: 'Charles Bukowski', quote: 'İnsan her zaman ihanet eder sonunda. Kimseye güvenme.' }, { author: 'Friedrich Nietzsche', quote: 'Oysa güzelliğin sesi kısıktır konuşurken; sadece en uyanık ruhlara yanaşır.' }, { author: 'Sabahattin Ali', quote: 'On beş günlük ömrü on beş seneye sığdıramazsın da, on beş senelik ömrü on beş günde yaşayıverirsin!' } ];

let random = 0;
  
function change() {
    let prev = quotes.splice(random,1)[0]; //remove the previous selection from the choices
    random = Math.floor(Math.random() * quotes.length);
    
    //quoteAuthor.innerHTML = quotes[random].author;
    //displayQuote.innerHTML = quotes[random].quote;
    console.log(`"${quotes[random].quote}" - ${quotes[random].author}`);
    
    quotes.push(prev); //add the previous selection back
}

//DEMO
for(let i=0;i<10;i++) change();


1
你需要跟踪你当前/旧的随机数,然后将其与新的随机数进行比较,并继续生成新的数字,直到获得一个新的数字,如下所示:
let random = 0;
let lastRandom = null;

function change() {
    do {
      random = Math.floor(Math.random() * quotes.length);
    } while(random === lastRandom);
    lastRandom = random;
    quoteAuthor.innerHTML = quotes[random].author;
    displayQuote.innerHTML = quotes[random].quote;
}

1
另一种方法可以是这样的:如果随机数与旧随机数相同,则调用change()函数。
<script>
const quotes = [
     {
        author: 'Ramiz Karaeski',
        quote: 'Meyvayı soymadan içinden ne çıkacak bilemem, kardeş.'
    },
    {
        author: 'Franz Kafka',
        quote: 'Beyinlerimiz savaşsın isterdim ama görüyorum ki silahsınız bayım.'
    },
    {
        author: 'Fyodor Dostoyevski',
        quote: 'Cehennem nedir? Sevginin artık imkansız olduğuna dair çekilen bir acıdır.'
    },
    {
        author: 'Lev Tolstoy',
        quote: 'Herkes dünyayı değiştirmeyi düşünür, ama kimse kendini değiştirmeyi düşünmez.'
    },
    {
        author: 'Charles Bukowski',
        quote: 'İnsan her zaman ihanet eder sonunda. Kimseye güvenme.'
    },
    {
        author: 'Friedrich Nietzsche',
        quote: 'Oysa güzelliğin sesi kısıktır konuşurken; sadece en uyanık ruhlara yanaşır.'
    },
    {
        author: 'Sabahattin Ali',
        quote: 'On beş günlük ömrü on beş seneye sığdıramazsın da, on beş senelik ömrü on beş günde yaşayıverirsin!'
    }
]


const quoteAuthor = document.getElementById('author');
const displayQuote = document.getElementById('quote');
const buttonChange = document.getElementById('button-change-quote');

buttonChange.addEventListener('click', change);

let random = 0;
change();

function change() {
var new_index = Math.floor(Math.random() * quotes.length);
if(new_index==random){
change();
return;
}else{
random=new_index;
}
    quoteAuthor.innerHTML = quotes[random].author;
    displayQuote.innerHTML = quotes[random].quote;
} 
</script>

1
有一个更好的方式:增加一个额外的变量来保存上一个引用。随机选择一个新的引用,然后交换这两个引用,这样新选择的引用就从选择列表中删除了。
const chosen = quotes.splice(random,1)[0]

function change() {
    new_choice = Math.floor(Math.random() * quotes.length);
    // display quotes[new_choice]

    // Swap the "disabled" quote back into the list, removing the one just chosen.
    temp = chosen
    chosen = quotes[new_choice]
    quotes[new_choice] = temp
}

0

只需从其他可能性中选择:

let random = Math.floor(Math.random() * quotes.length);
change();

function change() {
    let previous = random;
    random = Math.floor(Math.random() * (quotes.length-1));
    if (random >= previous) {
        random+=1;
    }
    quoteAuthor.innerHTML = quotes[random].author;
    displayQuote.innerHTML = quotes[random].quote;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接