JSFiddle - React, Tailwind, and code Playground
by naryad
HTML
<div id="RobW-sample"></div>
<!-- Created as requested by http://stackoverflow.com/q/7085454/938089-->
CSS
#wordAnalysis td{padding:1px 3px 1px 5px;text-align:left}
.num-words-header{font-weight:bold;border-top:1px solid #000}
JavaScript
/*@author Rob W, created on 16-17 September, on request for Stackoverflow (http://stackoverflow.com/q/7085454/938089)
* This script will calculate words. For the simplicity and efficiency,
* there's only one loop through a block of text.
* A 100% accuracy requires much more computing power, which is usually unnecessary
*/
var text = "A quick brown fox jumps over the lazy old bartender who said 'Hi!' as a response to the visitor who presumably assaulted the maid's brother, because he didn't pay his debts in time. In time in time does really mean in time. Too late is too early? Nonsense! 'Too late is too early' does not make any sense.";
var atLeast = 2; //show results with at least .. occurences
var numWords = 5; //Show statistics for one to .. words
var ignoreCase = true; //case-sensitive
var REallowedChars = /[^a-zA-Z'-]+/g;
// RE pattern to select valid characters. Invalid characters are replaced by a whitespace
//Prepare key map
var keys = [,]; //"keys[0] = undefined", a word boundary with length zero is empty
var results = [];
numWords++;//for human logic, we start counting at 1 instead of 0
for(var i=1; i<=numWords; i++){
keys.push({});
}
//Strip away all irrelevant characters
text = text.replace(REallowedChars, " ").replace(/^\s+/,"").replace(/\s+$/,"");
//create a mapping
if(ignoreCase) text = text.toLowerCase();
text = text.split(/\s+/);
for(var i=0,textlen=text.length,s; i<textlen; i++){
s = text[i];
keys[1][s] = (keys[1][s] || 0) + 1;
for(var j=2; j<=numWords; j++){
if(i+j <= textlen){
s += " " + text[i+j-1];
keys[j][s] = (keys[j][s] || 0) + 1;
} else break;
}
}
//prepares results for advanced analysis
for(var k=1; k<=numWords; k++){
results[k] = [];
var key = keys[k];
for(var i in key){
if(key[i] >= atLeast) results[k].push({"word":i, "count":key[i]});
}
}
//result parsing
var outputHTML = [];//Going to hold data for a table, innerHTML is much faster thus...