patternjavascriptMinor
Text Analysis web page
Viewed 0 times
textanalysispageweb
Problem
For a homework assignment, I made a web page that has a text area. The user inputs some text, hits the analyse button, and the output is supposed to be a list of the frequency of words of a given number of characters.
For example, "one two three" would be two words of three characters and one word of five characters.
It works, but is there room for improvement?
HTML:
JavaScript:
For example, "one two three" would be two words of three characters and one word of five characters.
It works, but is there room for improvement?
HTML:
Text Input
Click to analyze
Results
JavaScript:
function getWordInfo() {
var text1 = document.getElementById("text").value;
var text2 = text1.replace(/[^\d\w ]+/g," ");
var text3 = text2.split(/[ ]+/);
return text3;
}
function firstLoop() {
var text = getWordInfo();
var wordMap = [];
var i =0;
var looplength = text.length;
for ( i ;i " + str[i] + "";
}
document.getElementById("results").innerHTML += html;
}
function init() {
var button = document.getElementById("analyse");
button.onclick = analyseButtonClick;
}
window.onload = init;Solution
Here's a different approach, using the DOM instead of innerHTML, and using document fragments to append all at once and improve performance. Also you don't need that many regex, specially if you're copy/pasting them; splitting by any whitespace character and removing empty elements from the resulting array will do.
Then you could make use of the builtin higher-order functions such as
Demo: http://jsbin.com/motoy/1/edit
To learn more about these idioms, I'd recommend reading JavaScript Allonge, and Functional JavaScript. For JavaScript documentation visit the MDN
Then you could make use of the builtin higher-order functions such as
map and reduce to minimize the use of for loops and make the code a bit cleaner:var doc = document;
var extend = function(a, b) {
Object.keys(b).forEach(function(k){a[k] = b[k]});
return a;
};
var elem = function(tag, props) {
return extend(doc.createElement(tag), props);
};
/**
* @param words {Array}
* @returns {Object} Frequency of words per length
*/
var frequency = function(words) {
return words.filter(Boolean).reduce(function(acc, x) {
acc[x.length] = ++acc[x.length] || 1;
return acc;
},{});
};
var empty = function(x) {
while (x.hasChildNodes())
x.removeChild(x.lastChild);
return x;
};
/**
* @param freq {Object} Frequence of words per length
* @returns {Node} Document fragment
*/
var resultOf = function(freq) {
return Object.keys(freq).reduce(function(frag, k) {
frag.appendChild(elem('p', {
textContent: 'Words with '+ k +' chars: '+ freq[k]
}));
return frag;
}, doc.createDocumentFragment());
};
var textarea = doc.getElementById('text');
var button = doc.getElementById('analyse');
var result = doc.getElementById('results');
button.addEventListener('click', function() {
var res = resultOf(frequency(textarea.value.split(/\s+/)));
empty(result).appendChild(res);
});Demo: http://jsbin.com/motoy/1/edit
To learn more about these idioms, I'd recommend reading JavaScript Allonge, and Functional JavaScript. For JavaScript documentation visit the MDN
Code Snippets
var doc = document;
var extend = function(a, b) {
Object.keys(b).forEach(function(k){a[k] = b[k]});
return a;
};
var elem = function(tag, props) {
return extend(doc.createElement(tag), props);
};
/**
* @param words {Array}
* @returns {Object} Frequency of words per length
*/
var frequency = function(words) {
return words.filter(Boolean).reduce(function(acc, x) {
acc[x.length] = ++acc[x.length] || 1;
return acc;
},{});
};
var empty = function(x) {
while (x.hasChildNodes())
x.removeChild(x.lastChild);
return x;
};
/**
* @param freq {Object} Frequence of words per length
* @returns {Node} Document fragment
*/
var resultOf = function(freq) {
return Object.keys(freq).reduce(function(frag, k) {
frag.appendChild(elem('p', {
textContent: 'Words with '+ k +' chars: '+ freq[k]
}));
return frag;
}, doc.createDocumentFragment());
};
var textarea = doc.getElementById('text');
var button = doc.getElementById('analyse');
var result = doc.getElementById('results');
button.addEventListener('click', function() {
var res = resultOf(frequency(textarea.value.split(/\s+/)));
empty(result).appendChild(res);
});Context
StackExchange Code Review Q#54269, answer score: 3
Revisions (0)
No revisions yet.