Armin Nikdel
Armin Nikdel

Reputation: 335

How to scramble a sentence in Javascript preserving space location?

I found an script that will shuffle the string:

String.prototype.shuffle = function () {
    var a = this.split(""),
        n = a.length;

    for (var i = n - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
    return a.join("");
}

Using this script, following word:

What is the difference in between 'Apache Environment', 'Environment' and 'PHP Variables'?

will be shuffeled to this word on random basis:

ftewE'eim rasent  VhiEAn'oeded ta ' mb one'ennfva'nbcr?n elcttpnP iaWePh'irH rshv ieinena,

However, I am wondering how to preserve original location of each space:

ftew E' eim rasentVhiE An 'oededt a'mbone 'ennfva'nbcr? nelcttpnPiaWe Ph' irHr shvieinena,

Upvotes: 2

Views: 525

Answers (2)

Akrion
Akrion

Reputation: 18515

You could also simply check in your function if a[i] & a[j] are empty spaces:

const shuffleMeSoftly = function(str, breaker = ' ') {
  var a = str.split(""),
      n = a.length;

  for (var i = n - 1; i > 0; i--) {
    if (a[i] != breaker) {
      var j = Math.floor(Math.random() * (i + 1));
      if (a[j] != breaker) {
        var tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
      }
    }
  }
  return a.join("");
}

console.log(shuffleMeSoftly('What is the difference in between \'Apache Environment\', \'Environment\' and \'PHP Variables\'?'))

Upvotes: 3

CertainPerformance
CertainPerformance

Reputation: 370779

One option would be to create an array of randomized characters (no spaces), then call replace on the original string with a regular expression that replaces non-space characters with an item in the array at the associated index, incrementing the index in the process:

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

String.prototype.shuffle = function () {
  // pass to shuffleArray an array of all non-whitespace characters:
  const randomChars = shuffleArray([...this.replace(/\s+/g, '')]);
  let index = 0;
  // `\S` matches any non-whitespace character:
  return this.replace(/\S/g, () => randomChars[index++]);
}

console.log(
  `What is the difference in between 'Apache Environment', 'Environment' and 'PHP Variables'?`
  .shuffle()
);

Also note that mutating the built-in objects like String.prototype is generally considered quite poor practice, and can break things; unless you're polyfilling something official, it would be better to use a standalone function:

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

function shuffle(str) {
  const randomChars = shuffleArray([...str.replace(/\s+/g, '')]);
  let index = 0;
  return str.replace(/\S/g, () => randomChars[index++]);
}

console.log(shuffle(
  `What is the difference in between 'Apache Environment', 'Environment' and 'PHP Variables'?`
));

Upvotes: 1

Related Questions