Check how many times a string is inside a string - javascript

I got this string:
var longText="This is a superuser test, super user is is super important!";
I want to know how many times the string "su" is in longText and the position of each "su".
I was trying with:
var nr4 = longText.replace("su", "").length;
And the difference of lenght between the main text and the nr4 divided by "su" lenght beeing 2 is resulting a number of repetitions but i bet there is a better way of doing it.

For example
var parts=longText.split("su");
alert(parts.length-1); // length will be two if there is one "su"
More details using exec
FIDDLE
var re =/su/g, pos=[];
while ((result = re.exec(longText)) !== null) {
pos.push(result.index);
}
if (pos.length>0) alert(pos.length+" found at "+pos.join(","));

Use exec. Example amended from the MDN code. len contains the number of times su appears.
var myRe = /su/g;
var str = "This is a superuser test, super user is is super important!";
var myArray, len = 0;
while ((myArray = myRe.exec(str)) !== null) {
len++;
var msg = "Found " + myArray[0] + ". ";
msg += "Next match starts at " + myRe.lastIndex;
console.log(msg, len);
}
// "Found su. Next match starts at 12" 1
// "Found su. Next match starts at 28" 2
// "Found su. Next match starts at 45" 3
DEMO

Could do :
var indexesOf = function(baseString, strToMatch){
var baseStr = new String(baseString);
var wordLen = strToMatch.length;
var listSu = [];
// Number of strToMatch occurences
var nb = baseStr.split(strToMatch).length - 1;
for (var i = 0, len = nb; i < len; i++){
var ioF = baseStr.indexOf(strToMatch);
baseStr = baseStr.slice(ioF + wordLen, baseStr.length);
if (i > 0){
ioF = ioF + listSu[i-1] + wordLen;
}
listSu.push(ioF);
}
return listSu;
}
indexesOf("This is a superuser test, super user is is super important!","su");
return [10, 26, 43]

var longText="This is a superuser test, super user is is super important!";
var count = 0;
while(longText.indexOf("su") != -1) { // NB the indexOf() method is case sensitive!
longText = longText.replace("su",""); //replace first occurence of 'su' with a void string
count++;
}

Related

Javascript median using for

So I'm trying to learn javascript, and I want to find the median of some numbers that I insert into a prompt when I click on the button "find median".
function Media()
{
var n = prompt("number of elements?");
var i = 1;
var s = 0;
for (i=1;i<=n;i++)
{
var m = prompt("insert # " +i);
s = s+m;
}
var media = s/n;
document.getElementById("rezultat").innerHTML = "result: " +media
}
I made a test with two numbers, 1 and 2, and the median was 6, and i cant figure what i've done wrong
You should parse the result of prompt to an integer;
How to convert a string to an integer in JavaScript?
function Media() {
var n = parseInt(prompt("number of elements?"));
var i = 1;
var s = 0;
for (i=1;i<=n;i++)
{
var m = prompt("insert # " +i);
m = parseInt(m);
s = s+m;
}
var media = s/n;
document.getElementById("rezultat").innerHTML = "result: " +media
}
Media();
<div id='rezultat' />
You should also parse the result of prompt using parseInt
var m = parseInt(prompt("insert # " + i));
s/n gives the mean of the input. If you are looking for the median, you should use an array to store the inputs and get the element(s) in the middle.

Better way to slice up a string?

I'm trying to take a string with blank spaces and display each word line-by-line in console output.
My javascript code takes a string and creates an array of indexes where spaces are identified using an indexOf() operation. This is then passed through a slice loop which subtracts the different indexes to get a length of the string to slice and the space index to locate it in the existing string. The output is the final console.log and it appears to do what I need it to even when passing in random strings.
var sp = " ";
var myStr = "I am a \"double quoted\" string inside \"double quotes\""
var twoStr = 'I am a string "and I am a string"';
var stringadd = "and I can slice whenever I want."
var threeStr = myStr + sp + twoStr;
var fourStr = threeStr + sp + stringadd;
console.log("string length = ", fourStr.length);
var i = 0;
var n = 0;
var sentence = [i];
for (n = 0; n < fourStr.length; n++) {
var pos = fourStr.indexOf(sp, n) //find the index of the space
if (n == pos) {
sentence[i] = pos; //place the index in an array
i++;
} else(i);
}
var arraysent = fourStr.split(sp); //test split function for string
console.log("Array Sentence:\n", arraysent)
console.log("space index length:\n", sentence.length) //check array length
console.log("space index array:\n", sentence) //display array with "space" indexes
console.log("sliced string:\n", fourStr.slice(sentence[0] - 1, sentence[0])); //display first index
var j = 0;
for (j = 0; j < sentence.length; j++) {
var slicesent = fourStr.slice(sentence[j], sentence[j + 1]); //automate remaining index display
console.log(slicesent);
}
I was hoping to find an easier/simpler way to do this same task since passing the string to the array is not efficient and re-creates the string a bunch of times. Could someone please explain a better alternative that will show the individual words of a string line-by-line in the console?
Thank you
This is literally done by String.split()
function logWordsBySpaces(str){
let arr = str.split(" ");
arr.forEach(function(a){ console.log(a); })
}
logWordsBySpaces("Karma karma karma karma karma chameleon!")
You should use .split
var sp = " ";
var myStr = "I am a \"double quoted\" string inside \"double quotes\""
var twoStr = 'I am a string "and I am a string"';
var stringadd = "and I can slice whenever I want."
var threeStr = myStr + sp + twoStr;
var fourStr = threeStr + sp + stringadd;
const result = [myStr, twoStr, stringadd, threeStr, fourStr].map(string => string.split(sp));
console.log(result);

Find second occurrence of a character in a string

I have heard that JavaScript has a function called search() that can search for a string ( lets call it A ) in another string ( B ) and it will return the first position at which A was found in B.
var str = "Ana has apples!";
var n = str.search(" ");
The code should return 3 as its the first position in which the space was found in str.
And I was wondering if there is a function that can find the next spaces in my string.
For example I want to find the length of the first word in my string and I could easily do this If I knew the its starting position and its ending one.
If there is such a function, are there any better than it for such things?
You need to use String.indexOf method. It accepts the following arguments:
str.indexOf(searchValue[, fromIndex])
So you can do this:
var str = "Ana has apples!";
var pos1 = str.indexOf(" "); // 3
var pos2 = str.indexOf(" ", pos1 + 1); // 7
console.log(pos2 - pos1 - 1); // 3... length of the second word
.indexOf(…) will give you the first occurence of the " " (starting at 0):
var str = "Ana has apples!";
var n = str.indexOf(" ");
console.log(n);
If you want all occurences, this can be achieved easily using a RegExp with a while:
var str = "Ana has apples! A lot.";
var re = new RegExp(" ","ig");
var spaces = [];
while ((match = re.exec(str))) {
spaces.push(match.index);
}
// Output the whole array of results
console.log(spaces);
// You can also access the spaces position separately:
console.log('1st space:', spaces[0]);
console.log('2nd space:', spaces[1]);
⋅
⋅
⋅
Or… you can use a do {} while () loop:
var str = "Ana has apples! A lot.";
var i = 0,
n = 0;
do {
n = str.indexOf(" ");
if (n > -1) {
i += n;
console.log(i);
str = str.slice(n + 1);
i++;
}
}
while (n > -1);
Then, you can make a function of it:
var str = "Ana has apples! A lot.";
// Function
function indexsOf(str, sub) {
var arr = [],
i = 0,
n = 0;
do {
n = str.indexOf(" ");
if (n > -1) {
i += n;
arr.push(i);
str = str.slice(n + 1);
i++;
}
}
while (n > -1);
return arr;
}
var spaces = indexsOf(str, ' ')
// Output the whole array of results
console.log(spaces);
// You can also access the spaces position separately:
console.log('1st space:', spaces[0]);
console.log('2nd space:', spaces[1]);
⋅
⋅
⋅
Hope it helps.
Better for matching is to use regex. There is option like match group using group 'g' flag
var str = "Ana has apples !";
var regBuilder = new RegExp(" ","ig");
var matched = "";
while((matched = regBuilder.exec(str))){
console.log(matched + ", position : " +matched.index);
}
str = "Ana is Ana no one is better than Ana";
regBuilder = new RegExp("Ana","ig");
while((matched = regBuilder.exec(str))){
console.log(matched + ", position : " +matched.index);
}
'i' flag used to ignore case sensitive
You can check for other flags too here
Try this:
const str = "Ana has apples!";
const spaces = str.split('')
.map((c, i) => (c === ' ') ? i : -1)
.filter((c) => c !== -1);
console.log(spaces);
Then you will all the spaces positions.

Split string suing combination of string and length

I have a string like below, which i want to split using a number and "+", i tried with the below code,
Input String:
20001+20002+20003+20005+20019+20035+20009+20011+20015+20006+20020+20047+20048+20050+20049+204044+22407+20052+20057+20058+20059+20063+20065+20067+20068+20070+20072+20073+20075+20076+20078+20081+20084+20085+20086+20140+21954+206171+206170+206175+20093+206168+206177+206172+20098+206167+20107+20053+20054+20056+20108+20109+20110+20112+20115+20117+20119+20124+20126+20131+20132+20136+20141+20344+20345+20346+20348+20349+20355+20356.A
Code:
First found the len of the string,
var str1 = 20001+20002+20003+20005+20019+20035+20009+20011+20015+20006+20020+20047+20048+20050+20049+204044+22407+20052+20057+20058+20059+20063+20065+20067+20068+20070+20072+20073+20075+20076+20078+20081+20084+20085+20086+20140+21954+206171+206170+206175+20093+206168+206177+206172+20098+206167+20107+20053+20054+20056+20108+20109+20110+20112+20115+20117+20119+20124+20126+20131+20132+20136+20141+20344+20345+20346+20348+20349+20355+20356.A
str2 = str1.length;
if (str2 > '400') {
var str3 = str1.split("+", 100);
}else{
var str3 = str1
}
Desired Output:
str3[0] = 20001+20002+20003+20005+20019+20035+20009+20011+20015+20006+20020+20047+20048+20050+20049+204044+22407
str3[1] = 20052+20057+20058+20059+20063+20065+20067+20068+20070+20072+20073+20075+20076+20078+20081+20084+20085
str3[2] = 20086+20140+21954+206171+206170+206175+20093+206168+206177+206172+20098+206167+20107+20053+20054
str3[3] = 20056+20108+20109+20110+20112+20115+20117+20119+20124+20126+20131+20132+20136+20141+20344+20345
str3[4] = 20346+20348+20349+20355+20356.A
Length by default here is 100 and which should decrease based on the string rather than increasing (help need to accomplish this)
Please help me on this with some guidance
Almost the same as Nina Scholz's answer, but a little different. Starts from 0 then looks for the "+" after the next 100 characters then copies that to the result array. Starts again from the character after the "+" until the string is exhausted.
var s = '20001+20002+20003+20005+20019+20035+20009+20011+20015+20006+20020+20047+20048+20050+20049+204044+22407+20052+20057+20058+20059+20063+20065+20067+20068+20070+20072+20073+20075+20076+20078+20081+20084+20085+20086+20140+21954+206171+206170+206175+20093+206168+206177+206172+20098+206167+20107+20053+20054+20056+20108+20109+20110+20112+20115+20117+20119+20124+20126+20131+20132+20136+20141+20344+20345+20346+20348+20349+20355+20356.A';
var start = 0,
min = 100,
pos = 0,
result = [];
while (pos != -1) {
pos = s.indexOf('+', start + min);
result.push(s.substring(start, pos == -1? s.length : pos));
start = pos+1;
}
console.log(result);
You could use String#indexOf with a right start value as fromIndex to search for the next + and slice the string for the parts.
var string = '20001+20002+20003+20005+20019+20035+20009+20011+20015+20006+20020+20047+20048+20050+20049+204044+22407+20052+20057+20058+20059+20063+20065+20067+20068+20070+20072+20073+20075+20076+20078+20081+20084+20085+20086+20140+21954+206171+206170+206175+20093+206168+206177+206172+20098+206167+20107+20053+20054+20056+20108+20109+20110+20112+20115+20117+20119+20124+20126+20131+20132+20136+20141+20344+20345+20346+20348+20349+20355+20356.A',
length = 100,
start = 0,
pos,
result = [];
while ((pos = string.indexOf('+', start + length)) !== -1) {
result.push(string.slice(start, pos));
start = pos + 1;
}
result.push(string.slice(start));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Is this what you are looking for explanation in comments
var s = "20001+20002+20003+20005+20019+20035+20009+20011+20015+20006+20020+20047+20048+20050+20049+204044+22407+20052+20057+20058+20059+20063+20065+20067+20068+20070+20072+20073+20075+20076+20078+20081+20084+20085+20086+20140+21954+206171+206170+206175+20093+206168+206177+206172+20098+206167+20107+20053+20054+20056+20108+20109+20110+20112+20115+20117+20119+20124+20126+20131+20132+20136+20141+20344+20345+20346+20348+20349+20355+20356.A"
var d = [];
var slug = 100;//threshold value for separatuion
var rounds = Math.ceil(s.length/slug); //find how many elemnts shall be formed
console.log(rounds);
for(var i=0;i<rounds;i++){ //loop it
d.push(s.substr(0,slug)); //extract the basic initial string
//console.log(d,s,s.length) //extract the remaining string for next iteration
s = (s.length > slug) ? s.substr(slug) : s //make sure for last string less than slug value
}
console.log(d,d.length);

Highlighting string at multiple occurrences

I'm currently implementing a substring search. From the algorithm, I get array of substrings occurence positions where each element is in the form of [startPos, endPos].
For example (in javascript array):
[[1,3], [8,10], [15,18]]
And the string to highlight is:
ACGATCGATCGGATCGAGCGATCGAGCGATCGAT
I want to highlight (in HTML using <b>) the original string, so it will highlight or bold the string from position 1 to 3, then 8 to 10, then 15 to 18, etc (0-indexed).
A<b>CGA</b>TCGA<b>TCG</b>GATC<b>GAGC</b>GATCGAGCGATCGAT
This is what I have tried (JavaScript):
function hilightAtPositions(text, posArray) {
var startPos, endPos;
var startTag = "<b>";
var endTag = "</b>";
var hilightedText = "";
for (var i = 0; i < posArray.length; i++) {
startPos = posArray[i][0];
endPos = posArray[i][1];
hilightedText = [text.slice(0, startPos), startTag, text.slice(startPos, endPos), endTag, text.slice(endPos)].join('');
}
return hilightedText;
}
But it highlights just a range from the posArray (and I know it is still incorrect yet). So, how can I highlight a string given multiple occurrences position?
Looking at this question, and following John3136's suggestion of going from tail to head, you could do:
String.prototype.splice = function( idx, rem, s ) {
return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};
function hilightAtPositions(text, posArray) {
var startPos, endPos;
posArray = posArray.sort(function(a,b){ return a[0] - b[0];});
for (var i = posArray.length-1; i >= 0; i--) {
startPos = posArray[i][0];
endPos = posArray[i][1];
text= text.splice(endPos, 0, "</b>");
text= text.splice(startPos, 0, "<b>");
}
return text;
}
Note that in your code, you are overwriting hilightedText with each iteration, losing your changes.
Try this:
var stringToHighlight = "ACGATCGATCGGATCGAGCGATCGAGCGATCGAT";
var highlightPositions = [[1,3], [8,10], [15,18]];
var lengthDelta = 0;
for (var highlight in highlightPositions) {
var start = highlightPositions[highlight][0] + lengthDelta;
var end = highlightPositions[highlight][1] + lengthDelta;
var first = stringToHighlight.substring(0, start);
var second = stringToHighlight.substring(start, end + 1);
var third = stringToHighlight.substring(end + 1);
stringToHighlight = first + "<b>" + second + "</b>" + third;
lengthDelta += ("<b></b>").length;
}
alert(stringToHighlight);
Demo: http://jsfiddle.net/kPkk3/
Assuming that you're trying to highlight search terms or something like that. Why not replace the term with the bolding?
example:
term: abc
var text = 'abcdefgabcqq';
var term = 'abc';
text.replace(term, '<b>' + term + '</b>');
This would allow you to avoid worrying about positions, assuming that you are trying to highlight a specific string.
Assuming your list of segments is ordered from lowest start to highest, try doing your array from last to first.
That way you are not changing parts of the string you haven't reached yet.
Just change the loop to:
for (var i = posArray.length-1; i >=0; i--) {
If you want to check for multiple string matches and highlight them, this code snippet works.
function highlightMatch(text, matchString) {
let textArr = text.split(' ');
let returnArr = [];
for(let i=0; i<textArr.length; i++) {
let subStrMatch = textArr[i].toLowerCase().indexOf(matchString.toLowerCase());
if(subStrMatch !== -1) {
let subStr = textArr[i].split('');
let subStrReturn = [];
for(let j=0 ;j<subStr.length; j++) {
if(j === subStrMatch) {
subStrReturn.push('<strong>' + subStr[j]);
} else if (j === subStrMatch + (matchString.length-1)){
subStrReturn.push(subStr[j] + '<strong>');
} else {
subStrReturn.push(subStr[j]);
}
}
returnArr.push(subStrReturn.join(''));
} else {
returnArr.push(textArr[i]);
}
}
return returnArr;
}
highlightMatch('Multi Test returns multiple results', 'multi');
=> (5) ['<strong>Multi<strong>', 'Test', 'returns', '<strong>multi<strong>ple', 'results']

Categories