Please help to understand the part of JS code - javascript

i'm a new one in coding and learning the indexOf() method i found such part of code (see below)
I wonder why do we use the if() part in the code below. Why doesn't it work without it?
var myString = 'Welcome to Wrox books. ';
myString = myString + 'The Wrox website is www.wrox.com. ';
myString = myString + 'Visit the Wrox website today. Thanks for buying Wrox';
var foundAtPosition = 0;
var wroxCount = 0;
while (foundAtPosition != -1)
{
foundAtPosition = myString.indexOf('Wrox',foundAtPosition);
if (foundAtPosition != -1)
{
wroxCount++;
foundAtPosition++;
}
}
document.write('There are ' + wroxCount + ' occurrences of the word Wrox');
Will appreciate any thoughts.

You need the if to check if you have found the string you are looking for.
indexOf() will return -1 if the string is not found

The indexOf() method accepts two arguments: the substring to find in the given string, and the location(index) at which it should start searching for the substring. It returns the location(index) of the first occurrence of the substring(if the second argument is provided, it will be the first one after the provided location).
So, what the code inside the loop does:
Finds the location of the first occurrence of the substring using the indexOf() method and saves the location in the variable foundAtPosition.
If the substring was found(foundAtPosition!=-1), the wroxCount variable is incremented to indicate the number of substrings found so far, and the foundAtPosition variable is incremented as well(read on about it).
The while loop checks the condition, and if it is satisfied it executes its contents again.
The loop finds the location of the first occurrence of the substring, but now it starts searching at foundAtPosition. As the foundAtPosition variable was incremented by one, it will start searching after the previously found occurrence, and will return the location of the next one.
This goes on until there are no more occurrences left, which leaves the wroxCount variable containing the number of the occurrences of the substring in the main string.
The result: you get the number of times the word(substring) you are looking for occurs in the string myString.

You're counting the position of wrox everytime you found it. If you do not have more occourences, it won't increment the counter wroxCount because we don't want the counter to count after the foundAtPosition becomes -1. Or in other words, after last occourence, or if wrox is not found at all.

Related

Reverse lastIndexOf

I have a little question which I don't find any documentation about it (or it doesn't exist, or I'm searching in a wrong way..)
I have an ID which I want to get the whole string before the last character I choose.
In this case:
str_stringId = "AB_generalForm_DateTime_calendar";
str_dateId = str_firstId.substring(str_firstId.lastIndexOf("_") +1);
In this case, str_dateId returns "calendar", but I want the whole string behind it.
Is there a way to reverse this operation or do I need to count the number of letters of the whole string and then subtract with the length of "str_dateId" and after that, substring with the result?
Thank you.
The definition is string.substring(start,end) so you can simply
str_dateId = str_firstId.substring(0, str_firstId.lastIndexOf("_"));

Javascript selecting to save one index of split()

I have a value - toggle-save_2
I want to extract the 2 part. The part after the underscore will always be what i need but the length of the former part, which in this case is toggle-save_, may vary (eg. notoggle-val_45). Though this length may vary it will always be separated from the end number by an underscore.
Right now I am using this
var current = this.id.split('_');
current = current[1];
to select the number.
What would be cool is if I could pass a variable to the split to only give me the second index of the result from the split.
Just select the 2nd index when you do the split.
var current = this.id.split('_')[1];
The best solution here would be to use lastIndexOf and substring, like this
function getLastPart(strObject) {
return strObject.substring(strObject.lastIndexOf("_") + 1);
}
console.log(getLastPart("toggle-save_2"));
// 2
console.log(getLastPart("notoggle-save_45"));
// 45
It is better for this case because, you already know that the _ will be somewhere near the last position. Since lastIndexOf starts from the last position, it would find _ very soon and all we need to do is to get the rest of the string from the next position.
There are often times I am breaking up a string where I only need the very last value of the result of String.prototype.split and consider the rest to be garbage no matter how many values the split produced.
When those cases arise, I like to chain Array.prototype.pop off of the split
var s = 'toggle-save_2',
current = s.split('_').pop();
The split method can only be limited from the end, and it will always return an array.
You don't need to use split, you can use string operations to get part of the string:
var current = this.id.substr(this.id.indexOf('_') + 1);

Cutting strings

I'm following the excersises in the book Eloquent Javascript and came up to this piece of code:
function between(string, start, end)
{
// Start AT the last character position of the start string
var startAt = string.indexOf(start) + start.length;
//Count the position of the end string first character
var endAt = string.indexOf(end, startAt);
return string.slice(startAt, endAt);
}
var betweenIn = between('Inazuma Eleven', 'Ina', 'ven');
console.log(betweenIn);
Code works fine. It extracts a piece of string between in. Now I tried to really understand this piece, but one thing isn't clear to me. The variable endAt checks the string's first character position of the third given parameter, (in this case my string is 'Inazuma Eleven' end the parameter is 'ven'. I need that for slicing the string, BUT it seems that the second parameter of the indexOf method doesn't do anything. If I remove it, I get the same results. Why is this?
The second parameter of indexOf defaults to 0. This is the place in the string where it will start looking for your matching substring.
Starting after the end of the start string ensures that a) your end string doesn't match the first instance of it if the start string and end string are identical, and b) you have to scan less of the target string so the code runs faster.
In this instance, your start and end strings are different, so the outcome is the same. However since the indexOf method will be searching more of the string (starting from 0 instead of the 4th character) it will run fractionally slower.

Regex to extract substring, returning 2 results for some reason

I need to do a lot of regex things in javascript but am having some issues with the syntax and I can't seem to find a definitive resource on this.. for some reason when I do:
var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test)
it shows
"afskfsd33j, fskfsd33"
I'm not sure why its giving this output of original and the matched string, I am wondering how I can get it to just give the match (essentially extracting the part I want from the original string)
Thanks for any advice
match returns an array.
The default string representation of an array in JavaScript is the elements of the array separated by commas. In this case the desired result is in the second element of the array:
var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test[1]);
Each group defined by parenthesis () is captured during processing and each captured group content is pushed into result array in same order as groups within pattern starts. See more on http://www.regular-expressions.info/brackets.html and http://www.regular-expressions.info/refcapture.html (choose right language to see supported features)
var source = "afskfsd33j"
var result = source.match(/a(.*)j/);
result: ["afskfsd33j", "fskfsd33"]
The reason why you received this exact result is following:
First value in array is the first found string which confirms the entire pattern. So it should definitely start with "a" followed by any number of any characters and ends with first "j" char after starting "a".
Second value in array is captured group defined by parenthesis. In your case group contain entire pattern match without content defined outside parenthesis, so exactly "fskfsd33".
If you want to get rid of second value in array you may define pattern like this:
/a(?:.*)j/
where "?:" means that group of chars which match the content in parenthesis will not be part of resulting array.
Other options might be in this simple case to write pattern without any group because it is not necessary to use group at all:
/a.*j/
If you want to just check whether source text matches the pattern and does not care about which text it found than you may try:
var result = /a.*j/.test(source);
The result should return then only true|false values. For more info see http://www.javascriptkit.com/javatutors/re3.shtml
I think your problem is that the match method is returning an array. The 0th item in the array is the original string, the 1st thru nth items correspond to the 1st through nth matched parenthesised items. Your "alert()" call is showing the entire array.
Just get rid of the parenthesis and that will give you an array with one element and:
Change this line
var test = tesst.match(/a(.*)j/);
To this
var test = tesst.match(/a.*j/);
If you add parenthesis the match() function will find two match for you one for whole expression and one for the expression inside the parenthesis
Also according to developer.mozilla.org docs :
If you only want the first match found, you might want to use
RegExp.exec() instead.
You can use the below code:
RegExp(/a.*j/).exec("afskfsd33j")
I've just had the same problem.
You only get the text twice in your result if you include a match group (in brackets) and the 'g' (global) modifier.
The first item always is the first result, normally OK when using match(reg) on a short string, however when using a construct like:
while ((result = reg.exec(string)) !== null){
console.log(result);
}
the results are a little different.
Try the following code:
var regEx = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
var result = sample_string.match(regEx);
console.log(JSON.stringify(result));
// ["1 cat","2 fish"]
var reg = new RegExp('[0-9]+ (cat|fish)','g'), sampleString="1 cat and 2 fish";
while ((result = reg.exec(sampleString)) !== null) {
console.dir(JSON.stringify(result))
};
// '["1 cat","cat"]'
// '["2 fish","fish"]'
var reg = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
while ((result = reg.exec(sampleString)) !== null){
console.dir(JSON.stringify(result))
};
// '["1 cat","1 cat","cat"]'
// '["2 fish","2 fish","fish"]'
(tested on recent V8 - Chrome, Node.js)
The best answer is currently a comment which I can't upvote, so credit to #Mic.

Using javascript regexp to find the first AND longest match

I have a RegExp like the following simplified example:
var exp = /he|hell/;
When I run it on a string it will give me the first match, fx:
var str = "hello world";
var match = exp.exec(str);
// match contains ["he"];
I want the first and longest possible match,
and by that i mean sorted by index, then length.
Since the expression is combined from an array of RegExp's, I am looking for a way to find the longest match without having to rewrite the regular expression.
Is that even possible?
If it isn't, I am looking for a way to easily analyze the expression, and arrange it in the proper order. But I can't figure out how since the expressions could be a lot more complex, fx:
var exp = /h..|hel*/
How about /hell|he/ ?
All regex implementations I know of will (try to) match characters/patterns from left to right and terminate whenever they find an over-all match.
In other words: if you want to make sure you get the longest possible match, you'll need to try all your patterns (separately), store all matches and then get the longest match from all possible matches.
You can do it. It's explained here:
http://www.regular-expressions.info/alternation.html
(In summary, change the operand order or group with question mark the second part of the search.)
You cannot do "longest match" (or anything involving counting, minus look-aheads) with regular expressions.
Your best bet is to find all matches, and simply compare the lengths in the program.
I don't know if this is what you're looking for (Considering this question is almost 8 years old...), but here's my grain of salt:
(Switching the he for hell will perform the search based on the biggest first)
var exp = /hell|he/;
var str = "hello world";
var match = exp.exec(str);
if(match)
{
match.sort(function(a, b){return b.length - a.length;});
console.log(match[0]);
}
Where match[0] is going to be the longest of all the strings matched.

Categories

Resources