5

I'm trying to do something that is fairly simple, but my code looks terrible and I am certain there is a better way to do things in javascript. I am new to javascript, and am trying to improve my coding. This just feels very messy.

All I want to do is to randomly change the order some words on a web page. In python, the code would look something like this:

s = 'THis is a sentence'
shuffledSentence = random.shuffle(s.split(' ')).join(' ')

However, this is the monstrosity I've managed to produce in javascript

//need custom sorting function because javascript doesn't have shuffle?
function mySort(a,b) {    
    return a.sortValue - b.sortValue;
}

function scrambleWords() {

    var content = $.trim($(this).contents().text());

    splitContent = content.split(' ');

    //need to create a temporary array of objects to make sorting easier
    var tempArray = new Array(splitContent.length);

    for (var i = 0; i < splitContent.length; i++) {
        //create an object that can be assigned a random number for sorting
        var tmpObj = new Object();
        tmpObj.sortValue = Math.random();
        tmpObj.string = splitContent[i];
        tempArray[i] = tmpObj;       
    }

    tempArray.sort(mySort);

    //copy the strings back to the original array
    for (i = 0; i < splitContent.length; i++) {
        splitContent[i] = tempArray[i].string;
    }

    content = splitContent.join(' ');       
    //the result
    $(this).text(content);      

}

Can you help me to simplify things?

  • This may be of interest: http://stackoverflow.com/questions/962802/is-it-correct-to-use-javascript-array-sort-method-for-shuffling – spender Apr 27 '10 at 19:51

5 Answers5

13

Almost similar to the python code:

var s = 'This is a sentence'
var shuffledSentence = s.split(' ').shuffle().join(' ');

For the above to work, we need to add a shuffle method to Array (using Fisher-Yates).

Array.prototype.shuffle = function() {
    var i = this.length;
    if (i == 0) return this;
    while (--i) {
        var j = Math.floor(Math.random() * (i + 1 ));
        var a = this[i];
        var b = this[j];
        this[i] = b;
        this[j] = a;
    }
    return this;
};
Anurag
  • 140,337
  • 36
  • 221
  • 257
1
String.prototype.shuffler=function(delim){
    delim=delim || '';
    return this.split(delim).sort(function(){
            return .5-Math.random()}).join(delim);
}

// to shuffle words, pass a space

var s='abc def ghi jkl mno pqr stu vwx yz' alert(s.shuffler(' '))

kennebec
  • 89
  • 2
  • Good, but slower than Fisher-Yates. – Eric Mickelsen Apr 27 '10 at 20:13
  • -1 : using random values in a sort comparison function leads to improperly randomized lists since the sort relies on the fact that if a < b and b < c then a < c. random numbers break this assumption and cause an uneven distribution of terms. – Eric Strom Apr 28 '10 at 06:38
1

This is very old question but can still be useful.
Here is a very easy way to do it using array.sort()

const s = 'This is very old question but can still be useful.';

console.log(s.split(' ').sort(() => Math.floor(Math.random() * Math.floor(3)) - 1).join(' '))
ben
  • 3,558
  • 1
  • 15
  • 28
0

This code is untested, but it is a rough idea of an alternative approach:

function scrambleWords(text) {
  var words = text.split(' ');
  var result = "";

  while(words.length > 0) {
    if(result.length > 0) { words += " "; }
    words += words.splice(Math.abs(Math.random() * (words.length - 1)), 1);
  }

  return result;
}

Basically, the idea is to randomly splice words out of the origonal text and rebuild the string.

NOTE: splice is a little slow (rebuilds array), so if performance matters, I wouldn't suggest this as optimal, but I think the code is simplier.

UPDATE: I like the shuffle answer better that was just posted as a better solution :D

Chris
  • 9
  • 1
  • I don't think this code quite works, and if it did, it would still be a very slow and biased shuffle, which means each possible permutation would not be equally likely. – Eric Mickelsen Apr 27 '10 at 20:08
0

Using sort method and Math method :

var arr =  ["HORSE", "TIGER", "DOG", "CAT"];
function shuffleArray(arr){
  return arr.sort( () => Math.floor(Math.random() * Math.floor(3)) - 1)  
}

// every time it gives random sequence
shuffleArr(arr);
// ["DOG", "CAT", "TIGER", "HORSE"]
// ["HORSE", "TIGER", "CAT", "DOG"]
// ["TIGER", "HORSE", "CAT", "DOG"]
Tejas Savaliya
  • 572
  • 7
  • 8