Skip to content

Instantly share code, notes, and snippets.

@craigmichaelmartin
Created June 27, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigmichaelmartin/c3b961a2a072355a2f8e to your computer and use it in GitHub Desktop.
Save craigmichaelmartin/c3b961a2a072355a2f8e to your computer and use it in GitHub Desktop.
Write a javascript function to take in a String, and output "n" similar looking strings.
/*
* Write a javascript function to take in a String,
* and output "n" similar looking strings.
*/
// Returns a number of similiar strings
// A similiar string: respects whitespace, capitalization, and type (number vs alpha)
var similarNStrings = (function() {
// Returns a random integer [min, max)
var getRandomInt = function(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
};
// Returns an array of length with sequential numbers
var arrayOfSequentialNumbers = function(length) {
return Array.apply(null, {length: length}).map(Number.call, Number);
};
// Returns a random lowercase letter
var getRandomLowerCaseLetter = function() {
return Math.random().toString(36).replace(/[^a-z]+/g, '').charAt(0);
};
// Returns a random letter capitalized letter
var getRandomUpperCaseLetter = function() {
return getRandomLowerCaseLetter().toUpperCase();
};
// Returns a string with a swapped out character
var replaceStringCharacter = function(string, index, character) {
return string.substring(0,index) + character + string.substring(index+1);
};
// Returns a copy of an array spliced
var splice = function(array, index, count) {
array = array.slice();
count !== void 0 ? array.splice(index, count) : array.splice(index, count);
return array;
};
// Returns a different similar (alpha / number and case sensitive) character
var getReplacementCharacter = function(character) {
var newCharacter;
if (isNaN(character)) {
if (character === character.toUpperCase()) {
newCharacter = getRandomUpperCaseLetter();
} else {
newCharacter = getRandomLowerCaseLetter();
}
} else {
newCharacter = '' + getRandomInt(0, 10);
}
if (newCharacter === character) {
return getReplacementCharacter(character);
}
return newCharacter;
};
// Returns a string with variations, but not touching whitepsace
var swapOutVariousNonWhiteSpaceCharacters = function(string, variations, arrayOfIndexes) {
arrayOfIndexes = arrayOfIndexes || arrayOfSequentialNumbers(string.length);
if (arrayOfIndexes.length === 0 || variations === 0) {
return string;
}
var index = getRandomInt(0, arrayOfIndexes.length);
var spot = arrayOfIndexes[index];
if (string.charAt(spot) === ' ') {
return swapOutVariousNonWhiteSpaceCharacters(string, variations, splice(arrayOfIndexes, index, 1));
}
string = replaceStringCharacter(string, spot, getReplacementCharacter(string.charAt(spot)));
return swapOutVariousNonWhiteSpaceCharacters(string, variations-1, splice(arrayOfIndexes, index, 1));
};
// Useful for filtering an array by primitive values
var onlyUnique = function(value, index, self) {
return self.indexOf(value) === index;
};
// Counts the number of possible variations for a string
var stringVariationCount = function(string) {
if (string.length === 1) {
return isNaN(string.charAt(0)) ? 25 : 9;
}
return (isNaN(string.charAt(0)) ? 25 : 9) * stringVariationCount(string.substring(1));
};
// Returns a number of similiar strings
// A similiar string: respects whitespace, capitalization, and type (number vs alpha)
return function(base, n, variations) {
variations = variations || getRandomInt(1,4);
if (n > stringVariationCount(base)) {
throw 'Cannot generate a greater number of strings than is possible';
}
var helper = function(base, n, variations, array) {
array = (array && array.filter(onlyUnique)) || [];
variations = variations || getRandomInt(1,4);
if (array.length === n) {
return array;
}
array.push(swapOutVariousNonWhiteSpaceCharacters(base, variations));
return helper(base, n, variations, array);
};
return helper(base, n, variations);
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment