jQuery: Count words with more than X characters in string - javascript

I have an input field and a textarea in a form. For each of those two fields I'd like to count the number of words, number of dots, and number of words longer than 7 characters.
I've already got the code for the two first numbers (number of words and number of dots), but I can't figure out how to count the number of words longer than 7 characters in each of the fields.
Can anyone help me out with this one?
Here is my current code (fiddle):
var titleElem = $('#title');
var numberOfWords = countWords(titleElem);
var numberOfDots = countDots(titleElem);
function countWords(input) {
var a, z, inputValue, total;
inputValue = input.val();
total = 0;
a = inputValue.replace(/\s/g, ' ');
a = a.split(' ');
for (z = 0; z < a.length; z++) { if (a[z].length > 0) total++; }
return total;
}
function countDots(input) {
var inputVal;
inputVal = input.val();
return inputVal.split(".").length - 1;
}

It depends what you classify as a word. Does that include hyphens/apostrophes? You could use a simple regex for this:
var wordCount = $("input").val().match(/[\w0-9]{8,}/gi).length
The {8,} ensures that it only captures words more than 7 characters in length.

Related

Sum the number equivalent of alphabets in a word until it's single digit? [duplicate]

This question already has answers here:
Sum up a number until it becomes 1 digit JS
(16 answers)
Closed 3 years ago.
I am trying to solve a problem where a user gives a text input then I have to convert the text into given numeric values, add them together unless the answer is a single digit number.
So far, I have been able to get input, transform them into given numbers and store them in an array. But I cannot figure out what I will do next. How I will add the values together until it is left a single digit number.
var values = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15,p:16,q:17,r:18,s:19,t:20,u:21,v:22,w:23,x:24,y:25,z:26};
var someText = prompt('');
someText = someText.trim();
someText = someText.match(/\S/g);
var result = "";
for (i = 0; i < someText.length; i++) {
result += values[someText[i]];
}
alert(result);
For Example if input is "action" then numeric values will be
=>1.3.20.9.15.14.
-Add these values together.
1+3+20+9+15+14 answer will be 62.
-As the Answer is a 2 digit number, we add the numbers again
e.g 62 = 6+2= 8.
Note:
If answer is more then 1 digits: e.g 199 => 1+9+9 => 19 => 1+9 => 10 = 1+0 = 1.
Answer must always be a single digit number.
You can use reduce() to get the sum of all the digits of string. If the result is single digit then return the the number otherwise call the function recursively.
You also don't need to hard code the object with letter values. Just use reduce() and chatCodeAt to make a string of numbers.
var someText = prompt('').trim().toLowerCase().match(/\S/g)
let result = someText.reduce((ac,a) => ac + (a.charCodeAt(0) - 96),'');
function findSum(num){
if(num.length === 1) return num;
else return findSum(String(num.split('').reduce((ac,a) => ac + +a,0)))
}
console.log(findSum(result))
Here's how you can do it:
var values = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15,p:16,q:17,r:18,s:19,t:20,u:21,v:22,w:23,x:24,y:25,z:26};
var someText = prompt('');
someText = someText.trim();
someText = someText.match(/\S/g);
var result = "";
for (i = 0; i < someText.length; i++) {
result += values[someText[i]];
}
// While the result is >9, which means that there's more than 1 digit
while(result > 9) {
// Cast result as String, so we can use charAt()
var stringedResult = String(result);
// Reset our result var, because we're going to recalculate it
result = 0;
// For each int in our result, we add them up (ex. 621 = 6+2+1)
for(var i=0; i<stringedResult.length; i++) {
// Cast the stringed result back to a number, and add it to our result variable
result += Number(stringedResult.charAt(i));
}
}
alert(result);
You should use a function to sum the values and return the value when it's one digit or call itself otherwise:
var values = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15,p:16,q:17,r:18,s:19,t:20,u:21,v:22,w:23,x:24,y:25,z:26};
var someText = prompt('');
someText = someText.match(/\S/g);
var result = 0;
function getSum(string) {
for (i = 0; i < string.length; i++) {
if (isNaN(string[i])) {
result += values[string[i]];
} else {
result += parseInt(string[i]);
}
}
if (result.toString().length > 1) {
var aux = result.toString();
result = 0;
return getSum(aux);
} else {
return result;
}
}
alert(getSum(someText));

Remove excess words from a textbox

I have a script which is almost complete but I can't figure out the last bit here. The script is meant to limit the amount of words that can be entered into a text area and if they go over the word limit these extra words are removed. I have the amount of words beyond the max labeled as overage. For instance, if you were to enter in 102 words, then the overage would be 2. How would I remove those two words from the text area?
jQuery(document).ready(function($) {
var max = 100;
$('#text').keyup(function(e) {
if (e.which < 0x20) {
return;
}
var value = $('#text').val();
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
if (wordCount == max) {
// Reached max, prevent additional.
e.preventDefault();
} else if (wordCount > max) {
<!--Edited to show code from user3003216-->
<!--Isn't working like this, textarea doesn't update.-->
var overage = wordCount - max;
var words = value.split(' ');
for(var i = 0; i<overage; i++){
words.pop();
}
}
});
});
The easiest way to approach this is just to count the number of words on keypress and go from there. Check whether there are more words than the amount allowed. If so, remove all the excess words: while (text.length > maxWords). Then just replace the value of the text box with the updated text.
fiddle
JavaScript
var maxWords = 10;
$("#myText").keypress(function (event) {
var text = $(this).val().split(" "); // grabs the text and splits it
while (text.length > maxWords) { // while more words than maxWords
event.preventDefault();
text.pop(); // remove the last word
// event.preventDefault() isn't absolutely necessary,
// it just slightly alters the typing;
// remove it to see the difference
}
$(this).val(text.join(" ")); // replace the text with the updated text
})
HTML
<p>Enter no more than 10 words:</p>
<textarea id="myText"></textarea>
CSS
textarea {
width: 300px;
height: 100px;
}
You can easily test whether it works by pasting more than maxWords—in this case, 10—words into the textarea and pressing space. All the extra words will be removed.
You can put below code into your else if statement..
else if (wordCount > max) {
var overage = wordCount - max;
var words = value.split(' ');
for(var i = 0; i<overage; i++){
words.pop();
}
}
And if you want to get your string back from that words, you can use join like below:
str = words.join(' ');
well it would be better to use java script so here you go:
var maxWords = 20;
event.rc = true;
var words = event.value.split(" ");
if (words.length>maxWords) {
app.alert("You may not enter more than " + maxWords + " words in this field.");
event.rc = false;
}
jsFiddle Demo
You can use val to re-value the text-box. The array slice method will allow you to pull the first 100 words out of the array. Then just join them with a space and stick them back in the text-box.
$(document).ready(function($) {
var max = 100;
$('#text').keyup(function(e) {
if (e.which < 0x20) {
return;
}
var value = $('#text').val();
var words = value.trim().split(/\s+/gi);
var wordCount = words.length;
if (wordCount == max) {
// Reached max, prevent additional.
e.preventDefault();
} else if (wordCount > max) {
var substring = words.slice(0, max).join(' ');
$("#text").val(substring + ' ');
}
});
});
While you've already accepted an answer I thought I might be able to offer a slightly more refined version:
function limitWords(max){
// setting the value of the textarea:
$(this).val(function(i,v){
// i: the index of the current element in the collection,
// v: the current (pre-manipulation) value of the element.
// splitting the value by sequences of white-space characters,
// turning it into an Array. Slicing that array taking the first 10 elements,
// joining these words back together with a single space between them:
return v.split(/\s+/).slice(0,10).join(' ');
});
}
$('#demo').on('keyup paste input', limitWords);
JS Fiddle demo.
References:
JavaScript:
Array.prototype.join().
Array.prototype.slice().
String.prototype.split().
jQuery:
on().
val().

for loop string each word

if this type character '這' = NonEnglish each will take up 2 word space, and English will take up 1 word space, Max length limit is 10 word space; How to get the first 10 space.
for below example how to get the result This這 is?
I'm trying to use for loop from first word but I don't know how to get each word in string...
string = "This這 is是 English中文 …";
var NonEnglish = "[^\u0000-\u0080]+",
Pattern = new RegExp(NonEnglish),
MaxLength = 10,
Ratio = 2;
If you mean you want to get that part of the string where it's length has reached 10, here's the answer:
var string = "This這 is是 English中文 …";
function check(string){
// Length of A-Za-z characters is 1, and other characters which OP wants is 2
var length = i = 0, len = string.length;
// you can iterate over strings just as like arrays
for(;i < len; i++){
// if the character is what the OP wants, add 2, else 1
length += /\u0000-\u0080/.test(string[i]) ? 2 : 1;
// if length is >= 10, come out of loop
if(length >= 10) break;
}
// return string from the first letter till the index where we aborted the for loop
return string.substr(0, i);
}
alert(check(string));
Live Demo
EDIT 1:
Replaced .match with .test. The former returns a whole array while the latter simply returns true or false.
Improved RegEx. Since we are checking only one character, no need for ^ and + that were before.
Replaced len with string.length. Here's why.
I'd suggest something along the following lines (assuming that you're trying to break the string up into snippets that are <= 10 bytes in length):
string = "This這 is是 English中文 …";
function byteCount(text) {
//get the number of bytes consumed by a string
return encodeURI(text).split(/%..|./).length - 1;
}
function tokenize(text, targetLen) {
//break a string up into snippets that are <= to our target length
var result = [];
var pos = 0;
var current = "";
while (pos < text.length) {
var next = current + text.charAt(pos);
if (byteCount(next) > targetLen) {
result.push(current);
current = "";
pos--;
}
else if (byteCount(next) == targetLen) {
result.push(next);
current = "";
}
else {
current = next;
}
pos++;
}
if (current != "") {
result.push(current);
}
return result;
};
console.log(tokenize(string, 10));
http://jsfiddle.net/5pc6L/

How to make a .replace loop in javascript?

I am currently trying to make a .replace function loop in javascript. What I am trying to do is replace a random character with a hyphen, but the part that I am struggling with is how to make it loop the replacing of the character to hyphen. Here is the code that I have so far:
var randHold;
var randomWord;
var randLetHold;
var dispWord;
var repLetHold;
var myWords = new Array("Spectrometer", "Bandwagonjghvyjh", "jvjyvyvilvyjlvyv",
"fruitjjyvtyvjv", "seventctcvtv", "weathertfhtcthc",
"undercfxdtfv"); // random letters to make words that have more than 10 letters
function level() {
randHold = parseInt((Math.random() * 6) + 1);//code to randomly pick a word from the above array
randomWord = myWords[randHold]; //code to call the random word from the array
randLetHold = (Math.random() * randomWord.length);//code to randomly pick a character from the random word chosen
repLetHold = randomWord.charAt(randLetHold);//code to call the random character
for (i = 1; i <= 3; i++) //loop to replace three random characters with a hyphen
{
dispWord = randomWord.replace(repLetHold," - ");//code to replace a random character with a hyphen
document.write(dispWord);//But all this does is display the word(with ONE hypenated character)three times.
}
}
Your code actually seems fine, the main issue is that you're declaring your random variables outside of your for loop. Doing this will only generate them once for the entire loop. Try this instead:
var dispWord;
var myWords = new Array("Spectrometer", "Bandwagonjghvyjh", "jvjyvyvilvyjlvyv",
"fruitjjyvtyvjv", "seventctcvtv", "weathertfhtcthc",
"undercfxdtfv"); // random letters to make words that have more than 10 letters
function level() {
for (i = 1; i <= 3; i++) //loop to replace three random characters with a hyphen
{
var randHold = parseInt((Math.random() * 6) + 1);//code to randomly pick a word from the above array
var randomWord = myWords[randHold]; //code to call the random word from the array
var randLetHold = (Math.random() * randomWord.length);//code to randomly pick a character from the random word chosen
var repLetHold = randomWord.charAt(randLetHold);//code to call the random character
dispWord = randomWord.replace(repLetHold," - ");//code to replace a random character with a hyphen
document.write(dispWord);//But all this does is display the word(with ONE hypenated character)three times.
}
}
For 3 random characters to be hyphenated in the word, you want something like this.
<div id="result"></div>
var myWords = ["Spectrometer", "Bandwagonjghvyjh", "jvjyvyvilvyjlvyv",
"fruitjjyvtyvjv", "seventctcvtv", "weathertfhtcthc",
"undercfxdtfv"]; // random letters to make words that have more than 10 letters
var randomWord;
var dispWord;
var repLetHold = [];
function uniqueCount(str) {
var unique = [];
Array.prototype.forEach.call(str, function (value) {
if (unique.indexOf(value) === -1) {
unique.push(value);
}
});
return unique.length;
}
function level() {
var randHold = Math.floor(Math.random() * myWords.length);
dispWord = randomWord = myWords[randHold];
if (uniqueCount(randomWord) > 2) {
var count = 0,
temp1,
temp2;
while (count < 3) {
temp1 = Math.floor(Math.random() * dispWord.length);
temp2 = dispWord.charAt(temp1);
if (temp2 !== "-" && repLetHold.indexOf(temp2) === -1) {
dispWord = dispWord.replace(new RegExp(temp2, "g"), "-");
repLetHold[count] = temp2;
count += 1;
}
}
}
document.getElementById("result").textContent = dispWord;
}
level();
console.log(randomWord, repLetHold);
on jsfiddle
If you use a regular expression, you can replace all instances at once with the g (global) flag. For example:
var str = "this is a mass Spectrometer, which is a Spectrometer to detect the spectra of different masses";
var replaced = str.replace(/Spectometer/g, 'something');
// "this is a mass something, which is a something to detect the spectra of different masses";
Just keep in mind that some characters must be escaped inside regular expressions.
http://jsfiddle.net/zt8mp/
If i got the question right:
randomWord.replace(new RegExp(repLetHold,'g')," - ")
replaces all occurences of repLetHold (as long as it is not made of special regex characters)

jQuery: Count words in real time

I am using the following jQuery functionality to count words in real time:
$("input[type='text']:not(:disabled)").each(function(){
var input = '#' + this.id;
word_count(input);
$(this).keyup(function(){
word_count(input);
})
});
var word_count = function(field) {
var number = 0;
var original_count = parseInt($('#finalcount').val());
var matches = $(field).val().match(/\b/g);
if(matches) {
number = matches.length/2;
}
$('#finalcount').val(original_count + number)
}
The issue I am running into is that when I start typing in an input field, the count increases immediately by two, even on spaces and my delete key. Any ideas why this would happen?
I was following this tutorial: http://www.electrictoolbox.com/jquery-count-words-textarea-input/
Input:
<input class="widest" id="page_browser_title" name="page[browser_title]" size="30" type="text" value="">
Display Input:
<input class="widest" disabled="disabled" id="finalcount" name="page[word_count]" size="30" type="text" value="662">
It is incrementing with every key press because you are telling it to with:
$('#finalcount').val(original_count + number)
And if you add another word, you will find that it increments not by 2, but by 3. Presumably, you have several inputs on the page, and you intend for the finalcount input to display the number of words in each input. Either store the counts in a variable and add the variables together to get your finalcount value. Or count the words in each input every time.
var wordCounts = {};
function word_count (field) {
var number = 0;
var matches = $(field).val().match(/\b/g);
if (matches) {
number = matches.length / 2;
}
wordCounts[field] = number;
var finalCount = 0;
$.each(wordCounts, function(k, v) {
finalCount += v;
});
$('#finalcount').val(finalCount)
}
Working demo: http://jsfiddle.net/gilly3/YJVPZ/
Edit: By the way, you've got some opportunities to simplify your code a bit by removing some redundancy. You can replace all of the JavaScript you posted with this:
var wordCounts = {};
$("input[type='text']:not(:disabled)").keyup(function() {
var matches = this.value.match(/\b/g);
wordCounts[this.id] = matches ? matches.length / 2 : 0;
var finalCount = 0;
$.each(wordCounts, function(k, v) {
finalCount += v;
});
$('#finalcount').val(finalCount)
}).keyup();
http://jsfiddle.net/gilly3/YJVPZ/1/
Edit
Check this example.
Why don't you use split(" ") instead of matching and dividing the result? You will have an array containing all your words, the length of the array will be the number of words.
var matches = $(field).val().split(" ");
Also, why are you adding every time the matches to the old result?
$('#finalcount').val(original_count + number)
Isn't this adding every time all the words twice?

Categories