I need to write a function in javascript, which finds a string in a text and prints how many times the string is found in the text. Here is my code, It's not working for some reason.... Please help
var word = 'text',
text = 'This is some wierd stupid text to show you the stupid text without meaning text just wierd text oh text stupid text without meaning.';
searchWord(word, text);
function searchWord(word, text) {
switch (arguments.length) {
case 1: console.log('Invalid input, please try again'); break;
case 2: var array = text.split(' ');
for (var i = 0; i < array.length; i++) {
var count = 0;
if (array[i] === word) {
count ++;
}
}
console.log('Word ' + word + ' is repeated in the text ' + count + ' times');
}
}
There is a small problem in your code. You have to move
var count = 0;
outside the for loop.
Move
var count = 0;
Outside your loop
Your count variable should be outside of your for loop, else you are resetting it everytime you enter the loop.
function searchWord(word, text) {
switch (arguments.length) {
case 1: console.log('Invalid input, please try again'); break;
case 2: var array = text.split(' ');
var count = 0;//Place it here.
for (var i = 0; i < array.length; i++) {
if (array[i] === word) {
count ++;
}
}
console.log('Word ' + word + ' is repeated in the text ' + count + ' times');
}
}
You could just use a regular expression to count the occurences
var word = 'text',
text = 'This is some wierd stupid text to show you the stupid text without meaning text just wierd text oh text stupid text without meaning.';
searchWord(word, text);
function searchWord(word, text) {
var re = new RegExp(""+text+"", "g");
var count = (text.match(/text/g) || []).length;
console.log('Word ' + word + ' is repeated in the text ' + count + ' times');
}
Already answered but this is a short version of getting the count:
function getWordCount(word, text) {
if(arguments.length === 0) return;
var count = 0;
text.split(" ").forEach(function(val) {
if(val === word) count++;
});
}
A simple one line solution without loops or RegExp
This one line solution appears to work. Note that it appends a space to the head and tail of the sentence to catch matching words at ends. This could be done with a pure RegExp too, but then it wouldn't be one line ... and I like simple solutions.
return (' ' + text.toLowerCase() + ' ').split( ' ' + word.toLowerCase() + ' ' ).length - 1;
And refactoring the original code we can eliminate 10 extraneous lines and a loop:
function searchWord(word, text) {
return (' ' + text.toLowerCase() + ' ').split( ' ' + word.toLowerCase() + ' ' ).length - 1;
}
var word = 'text',
text = 'This is some wierd stupid text to show you the stupid text without meaning text just wierd text oh text stupid text without meaning.';
console.log('Word ' + word + ' is repeated in the text ' + searchWord(word,text) + ' times');
Related
The code is used in a HTML document, where when you press a button the first word in every sentence gets marked in bold
This is my code:
var i = 0;
while(i < restOftext.length) {
if (text[i] === ".") {
var space = text.indexOf(" ", i + 2);
var tekststykke = text.slice(i + 2, space);
var text = text.slice(0, i) + "<b>" + tekststykke + "</b>" + text.slice(i + (tekststykke.length + 2));
var period = text.replace(/<b>/g, ". <b>");
var text2 = "<b>" + firstWord + "</b>" + period.slice(space1);
i++
}
}
document.getElementById("firstWordBold").innerHTML = text2;
}
It's in the first part of the code under function firstWordBold(); where it says there is an error with
var space1 = text.indexOf(" ");
Looks like you're missing a closing quote on your string, at least in the example you provided in the question.
Your problem is the scope of the text variable. In firstWordBold change every text to this.text, except the last two where you re-define text
Also, if you want to apply bold to the first word this is easier...
document.getElementById('test-div-2').innerHTML = '<b>' + firstWord + '</b>' + restOftext;
It now works for me, with no errors and it applies bold to the first word.
Here's how the function ended up,
function firstWordBold() {
console.log('bolding!');
var space1 = this.text.indexOf(' ');
var firstWord = this.text.slice(0, space1);
var restOftext = this.text.slice(space1);
document.getElementById('test-div-2').innerHTML = '<b>' + firstWord + '</b>' + restOftext;
}
To make every first word bold, try this...
function firstWordBold() {
let newHTML = '';
const sentences = this.text.split('.');
for (let sentence of sentences) {
sentence = sentence.trim();
var space1 = sentence.indexOf(' ');
var firstWord = sentence.slice(0, space1);
var restOftext = sentence.slice(space1);
newHTML += '<b>' + firstWord + '</b>' + restOftext + ' ';
}
document.getElementById('test-div-2').innerHTML = newHTML;
}
One last edit, I didn't notice you had sentences ending with anything other that a period before. To split on multiple delimiters use a regex, like so,
const sentences = this.text.split(/(?<=[.?!])\s/);
I have set of numbers from an excel like this
05143
05250
05252
05156
05143
05441
05143
05031
05050
05101
05821
05822
05861
and after every 5th digit I wanted to add a ,
My problem is that after every 5th digit it considers a white space carriage as a digit and then split the items such as
05143 ↵0525 0↵052 50↵05 and so on...
and that's why , split is breaking. I tried to replace it as item.replace(/↵/g, ""); but its not working.
here is my code
item.replace(/↵/g, "")
console.log(item)
if(item.length > 5){
for (var i = 0; i < item.length; i += 5) {
chunks.push(item.substring(i, i + 5));
}
console.log(chunks)
var tempItem;
chunks.forEach(function(item2) {
if (tempItem == undefined) {
tempItem = "'" + item2 + "'";
} else {
tempItem = tempItem + ",'" + item2 + "'";
}
})
It's not clear from the question what character code you have in your string that cause the problem.
But I think that if you use this general replace you will solve.
item.replace(/\W/g, '')
it works when we write it as
item.split('\n')
I figured it out, thank you. I need to move the body to the html. Changed some tags in the body section.
}
else
{
window.alert ("You entered an invalid character (" + enterLetter + ") please re-enter");
secondPrompt();
}
}
</script>
<body onload = "firstPrompt();">
<h2>
Word Checker
</h2>
</body>
</html>
You can increment indexOf each time you find a match-
function indexFind(string, charac){
var i= 0, found= [];
while((i= string.indexOf(charac, i))!= -1) found.push(i++);
return found;
}
indexFind('It\'s more like it is today, than it ever was before','o');
/* returned value: (Array)
6,22,48
*/
Using indexOf recursively:
function findMatches(str, char) {
var i = 0,
ret = [];
while ((i = str.indexOf(char, i)) !== -1) {
ret.push(i);
i += char.length; //can use i++ too if char is always 1 character
};
return ret;
}
Usage in your code:
var matches = findMatches(enterWord, enterLetter);
if (!matches.length) { //no matches
document.write ("String '" + enterWord + "' does not contain the letter '" + enterLetter + ".<br />");
} else {
for (var i = 0; i < matches.length; i++) {
document.write ("String '" + enterWord + "' contains the letter '" + enterLetter + "' at position " + matches[i] + ".<br />");
}
}
Live Demo
Full source (with some tweaks from your last question)
I have a bit of code that searches the current information shown on the page from a input source, which is an XML loaded in. This then shows how many times the word has been found, it should then display the lines where the word was found although currently it is showing all the lines. The code is
function searchResults(query) {
var temp = "\\b" + query + "\\b";
var regex_query = new RegExp(temp, "gi");
var currentLine;
var num_matching_lines = 0;
$("#mainOutput").empty();
$("LINE", g_playDOM).each(
function() {
currentLine = $(this).text();
matchesLine = currentLine.replace(regex_query,
'<span class="query_match">' + query + '</span>');
if (currentLine.search(regex_query) > 0)
num_matching_lines++;
$("#mainOutput").append("<p>" + matchesLine + "</p>");
});
$("#sideInfo").append(
"<p>Found " + query + " in " + num_matching_lines + " lines</p>");
}
$(document).ready(function() {
loadPlay();
$("#term_search").focus(function(event) {
$(this).val("");
});
$("#term_search").keypress(function(event) {
if (event.keyCode == 13)
searchResults($("#term_search").val());
});
$('#term-search-btn').click(function() {
searchResults($("#term_search").val());
});
});
</script>
Currently the number of lines the word is on is being shown correctly.
If you want a line of code to be executed within a conditional, then you need to place curly braces around it. Otherwise, only the very next action item will be executed. In your case, increase the count of the number of lines that match.
Your subsequent action item, appending the found line into the DOM is executed on every branch because the if statement has already done its job. Offending lines below:
if ( currentLine.search(regex_query) > 0 ) num_matching_lines++;
$("#mainOutput").append("<p>" + matchesLine + "</p>");
Fixed:
if ( currentLine.search(regex_query) > 0 ) {
num_matching_lines++;
$("#mainOutput").append("<p>" + matchesLine + "</p>");
}
Is it possible to wrap the last words in a string with span tags excluding the first word? So it'd be for example:
var string = 'My super text';
Becomes
My <span>super text</span>
I have this:
var text = string.split(" ");
// drop the last word and store it in a variable
var last = text.pop();
// join the text back and if it has more than 1 word add the span tag
// to the last word
if (text.length > 0) {
return text.join(" ") + " <span>" + last + "</span>";
}
else {
return "<span>" + text.join(" ") + last + "</span>";
}
Which wraps the last word with span tags if it has at least two but not sure how to modify it.
You just need to use text.shift() which will return the first word, instead of text.pop() which returns the last word. Then it will be much easier to accomplish this.
var text= string.split(" ");
// get the first word and store it in a variable
var first = text.shift();
// join the text back and if it has more than 1 word add the span tag
// to the last word
if (text.length > 0) {
return first + " <span>" + text.join(" ") + "</span>";
} else {
return "<span>" + first + "</span>";
}
You could do it with a regular expression.
text = text.replace(/\s(.*)$/, ' <span>$1</span>');
However, you should probably turn the following into a recursive function...
$('body').contents().filter(function() {
return this.nodeType == 3;
}).each(function() {
var node = this;
// Normalise node.
node.data = $.trim(node.data);
node.data.replace(/\s+(.*)\s*$/, function(all, match, offset) {
var chunk = node.splitText(offset);
chunk.parentNode.removeChild(chunk);
var span = document.createElement('span');
span.appendChild(document.createTextNode(' ' + match));
node.parentNode.appendChild(span);
});
});
jsFiddle.
This will allow you to modify text nodes and insert the span elements without messing with serialised HTML.
var space = string.indexOf(' ');
if (space !== -1) {
return string.slice(0,space) + " <span>" + string.slice( space ) + "</span>";
} else {
return "<span>" + string + "</span>";
}
You don't have to split the text, just check if there is a space, and insert a span there.
This code inserts a span after the first space, and if there is no space (idx == -1), the span is put at the beginning of the string:
var idx = string.indexOf(' ');
return string.substr(0, idx + 1) + "<span>" + string.substr(idx + 1) + "</span>";