2

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.

3
  • You're subtracting 1 from the length of the array but never reducing the size of the array itself - it is infinite. Commented Jan 5, 2017 at 21:38
  • What is purpose of else { i--; }? Commented Jan 5, 2017 at 21:45
  • else { i-- } will subtract one from the loop run if the word already exists in the new paragraph. @Press I see what you are saying I think. You mean here: words[getRandomNumber(0,words.length - 1)]; or do you mean i--; Commented Jan 5, 2017 at 21:52

3 Answers 3

2

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.

Fiddle

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

Sign up to request clarification or add additional context in comments.

2 Comments

The only remaining issue is to fix the duplicate word problem mentioned by @Y.C. below. For example, "the" is listed three times. I should end up with a 19 word paragraph but I'm only ending up with a 13 word paragraph.
Oh! With this code, I don't need the if-statement at all. The words.splice removes the index of the item so it can't appear again. Thanks so much!
0

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.

Comments

0

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.

5 Comments

Could you explain these two items to me: words.sort(function(a, b) { return 0.5 - Math.random(); }); and newPara = words.join(' ');
There are references in the MDN, Array.prototype.sort() link, Array.prototype.join() link
The join() method joins all elements of an array into a string.The sort() method sorts the elements of an array in place according to the method your offered and returns the array.
I see. I was looking for a way to randomly generate the order words of the paragraph each time the page was refreshed. It doesn't sound like these methods will do that? Hence the question. But maybe I am missing something.
My code is a simple way to achieve that, you can try it, basically it will shuffle the sentence.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.