Reputation: 93
I am trying to rebuild a paragraph of words randomly without repeating the same word in JavaScript:
var para = 'dashing through the snow' +
' in a one horse open sleigh' +
' over the fields we go' +
' laughing all the way';
console.log(para);
function getRandomNumber(min, max)
{
return Math.floor(Math.random() * (max - min)) + min;
}
var words = para.split(' ');
var newPara = '';
for(var i = 0; i < words.length - 1; i++)
{
var curWord = words[getRandomNumber(0,words.length - 1)];
if(newPara.indexOf(curWord) == -1)
{
newPara += curWord + ' ';
console.log(newPara);
} else
{
i--;
}
}
The code splits a paragraph into an array of words (19 in all). I then use a loop to loop through this array and select a word at random, checking if the word has been added to the newPara string. If it has not, I add it. If it has, I subtract 1 from the loop run. The problem is that the script causes the browser to freeze when I use the else statement to subtract one from the loop. Any help on this problem is appreciated.
Based on comments I made this edit:
if(newPara.length <= words.length)
{
if(newPara.indexOf(curWord) == -1)
{
newPara += curWord + ' ';
console.log(newPara);
} else
{
i--;
}
}
However, I am still getting the same error.
Upvotes: 2
Views: 250
Reputation: 727
Try this code:
var para = 'dashing through the snow' +
' in a one horse open sleigh' +
' over the fields we go' +
' laughing all the way';
var words, newPara = '';
console.log(para);
words = para.split(' ');
words.sort(function(a, b) {
return 0.5 - Math.random();
});
newPara = words.join(' ');
console.log(newPara);
The problem in your code is that some word in your para
repeats several times, like the word 'the' occurs 3 times, it will never meet the condition: i === words.length - 1
.
var para = 'dashing through the snow' +
' in a one horse open sleigh' +
' over the fields we go' +
' laughing all the way';
There is also a bug in your random number generating algorithm, which makes it extremely difficult to get the last number words[words.length-1]
, changing getRandomNumber(0, words.length - 1)
to getRandomNumber(0, words.length)
will make it work.
Upvotes: 0
Reputation: 535
What you are creating is an infinite loop. If a word which is already used is picked by the random number generator for 2 more times, your loop counter is subtracted by 2. Eventually when all words are used (lets assume that there are only chosen 1 or 2 times) your i
is always smaller than words.length
(hence, the condition is never met).
A possible solution is to save the length of the paragraph in a variable and use that in your loop condition. Then for every word you choose, you remove it from the words
array.
This wil not end up in a infinite loop and will also minimize your number of iterations, since there are no more misses when trying to find a word.
Upvotes: 0
Reputation: 2927
The solution I came up with is to work backwards from words.length
to 0 and remove the word from the array if it has already been used.
var para = 'dashing through the snow' +
' in a one horse open sleigh' +
' over the fields we go' +
' laughing all the way';
function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
var words = para.split(' ');
var newPara = '';
for (var i = words.length; i > 0; i--) {
var rand = getRandomNumber(0, words.length - 1),
curr = words[rand];
if (newPara.indexOf(curr) == -1) {
newPara += curr + ' ';
words.splice(rand, 1);
}
}
console.log(newPara);
Upvotes: 2