indexOf with Nothing Before String - javascript

I have a string which contains the following:
string = "GOAT,Speed,OCG GOAT";
I then have the following:
if(data.format.indexOf("GOAT") >= 0){
}
if(data.format.indexOf("OCG GOAT") >= 0){
}
Both of them naturally return as TRUE because "GOAT" is contained in both of them.
Is it possible to do an indexOf where nothing comes before the string so I can do only a check on "GOAT" and not have "OCG GOAT" return true? Because "GOAT" will always come first in the string.

Either check that the indexOf is equal to 0 (indicating that the substring you're searching for occurs at the very beginning of the haystack):
data.format.indexOf('GOAT') === 0
Or use startsWith instead:
data.format.startsWith('Goat')

Using regular expressions could be a solution, too:
const GOAT_REGEX = /^GOAT.*/g;
const SUCCESS = "GOAT,Speed,OCG GOAT";
const FAILURE = "Speed,OCG GOAT";
console.log('Should work (true is correct)', GOAT_REGEX.test(SUCCESS));
console.log('Should fail (false is correct)', GOAT_REGEX.test(FAILURE));

Related

How to check if a string is inside another string (but not on the edge)?

Let's say I have this string: abc/def. How would I check if there is a slash inside the string but not on the edge? For example, a slash at the very end like abcdef/ or the very start like /abcdef is not allowed.
In this case, String#includes doesn't work since that includes all possible locations. How do I achieve this?
You could take a substring and check with includes.
const check = s => s.slice(1, -1).includes('/');
console.log(['abc/def', '/def', 'abc/'].map(check));
You could use a simple regex to check the string:
"abc/def".test(/.\/./) // true
"/abcdef".test(/.\/./) // false
"abcdef/".test(/.\/./) // false
Alternatively, you could get the index of the / and compare it with the length of the string.
const str = "abc/def"
const i = str.indexOf("/")
i > 0 && i < str.length - 1 // true
You could also use inside-string:
const insideString = require("inside-string")
insideString("abc/def", "/") // true
You could use a regular expression:
function test(input, search) {
return new RegExp(`^.+${search}.+$`).test(input);
}
console.log(test("abcde/f", "\/"));
console.log(test("abcdef/", "\/"));

How can i write function called validate(z) which takes a string as argument & return true if contain 1 "#" symbol & at least 1 "." & false otherwise

I have just started to learn functions and am finding it quite difficult.
I have learnt a few different functions but I haven't ever done a function like this.
How do I write a function called validate(z) which takes a string as an argument and returns true if it contains one # symbol and at least one dot . and false otherwise.
E.g. if z = "stack#overflow.co.uk" the function will return true.
Regex seems like a lot of overkill for such a simple requirement. I'd go with something like this
function validate(z) {
var hasDots = z.indexOf('.') !== -1,
firstAt = z.indexOf('#'),
lastAt = z.lastIndexOf('#');
return hasDots && firstAt !== -1 && firstAt === lastAt;
}
It sounds like what you're looking for is an email validation function. These are a lot more tricky to write than you may expect. You have to validate length as well as format. Here's one that's worked well for me in all of my implementations using a (quite complicated) regex statement.
function validateEmail(v) {
var r = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
return (v.match(r) == null) ? false : true;
}
You can use regex.
function validate(z) {
var re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(z);
}
For the dot, use indexOf to search for the character in the input:
function contains(z, c) {
return z.indexOf(c) !== -1;
}
To check for a single #, you could say
function contains_one(z, c) {
var first = z.indexOf(c);
var last = z.lastIndexOf(c);
return first !== -1 && first == last;
}
function validate(z) {
return contains_one(z, '#') && contains(z, '.');
}
If you prefer to use regexp:
function validate(z) {
return /^[^#]*#[^#]*\.[^#]*$/.test(z);
}
This says asks for a sequence of non-at-signs, followed by an at-sign, followed by a sequence of non-at-signs, followed by a dot, followed by a sequence of non at signs. You may want to tweak this. For instance, it insists that the dot be to the right of the at sign. Also, it allows the dot to come immediately after the at-sign, or immediately at the end of the input.

Javascript, string, RegEx, if and else if, console.log different output

I want to output a string's vowels in order, so I decided to use RegEx to do it.
However, when I put the expression in different position in (if and else if), the output is different for the same expression. Could anyone explain?
function ordered_vowel_word(str) {
if(str.match(/[aeiou]{1,}/g) !== ""){
var arr = str.match(/[aeiou]{1,}/g);
console.log(arr);
}
else
console.log(str);
}
ordered_vowel_word("bcg");
ordered_vowel_word("eebbscao");
/* The Output */
ordered_vowel_word("bcg");
==> null
ordered_vowel_word("eebbscao");
==> ["ee", "ao"]
But if I restructure the expression,
function ordered_vowel_word(str) {
if(str.match(/[^aeiou]/) !== "")
console.log(str);
else if(str.match(/[aeiou]{1,}/g) !== ""){
var arr = str.match(/[aeiou]{1,}/g);
console.log(arr);
}
}
The output will be
ordered_vowel_word("bcg");
==> bgv
ordered_vowel_word("eebbscao");
==> eebbscao
Take note that string.match returns an array if there is at least one match, and it returns null if there is no match.
What I think you want is :
if(str.match(/[aeiou]{1,}/g) == null){ // no matches
or
if(str.match(/[aeiou]{1,}/g) != null){ //has a match
As for the sorting, you have to do process the array you get with str.match.
Check out this SO answer for sorting arrays. Yes, you can use > and < operators for characters.
The return value of str.match the way you are using it is an array containing the matches when it matches. Also, it is not an empty string when there are no matches... it is actually null.
Try changing what you are testing for in your if condition to this:
str.match(/[aeiou]{1,}/g) !== null)

Javascript - search a string from beginning

Hello i currently have this part of the code that i developed but i want to do some edits:
$('#target').keydown(function(event) {
if (event.which == 13)
{
var users = ["Dennis Lucky","Lucy Foo","Name Lastname","Billy Jean"];
var match = 0;
var str = $('#target').val();
for(i=0;i<users.length;i++)
{
if ( users[i].toLowerCase().indexOf(str.toLowerCase()) > -1 )
{
match++;
name = users[i];
}
}
if(match == 1)
{
$('#target').val('');
$('#chatbox').append('<span style="color:blue;">'+name+'</span> ');
console.log(name);
}
else if (match >= 2)
{
console.log("many entries");
}
}});
The idea is that if i type something and hit enter if the partial string exists in users becomes blue color.With this code i have the problem that if i write "Lu" i get 2 results, "Dennis Lucky" and "Lucy Foo".
I want to change my code so when i type "Lu" it will start searching the words starting with this sting and not include it.
if ( users[i].toLowerCase().indexOf(str.toLowerCase()) > -1 )
The condition is true if indexOf's returned value is greater than -1. In JavaScript, indexOf returns -1 if a match "needle" (the string you're searching for) isn't found in your "haystack" (the string that you're searching within). Otherwise, it returns the first index of the "needle" in your "haystack".
To explain my terminology of indexOf, here's an example:
haystack.indexOf(needle); // How to use the indexOf function
console.log("apples oranges apples".indexOf("apples")); // This would print 0.
console.log("apples oranges apples".indexOf("white")); // This would print -1.
If you want to ensure that the string starts with the "needle", you simply need to change your code to
if ( users[i].toLowerCase().indexOf(str.toLowerCase()) == 0 )
If you want your "words" ("Lucy Foo" would be "Lucy" and "Foo"), either split your name strings by a space character and perform the indexof search with the elements of the resultant array, or turn to regex.
It is better to use regexes. Since you want to search the start of string use ^
Refer Regular Expressions documentation on MDN for more information.

How to know if JavaScript string.replace() did anything?

The replace function returns the new string with the replaces, but if there weren't any words to replace, then the original string is returned. Is there a way to know whether it actually replaced anything apart from comparing the result with the original string?
A simple option is to check for matches before you replace:
var regex = /i/g;
var newStr = str;
var replaced = str.search(regex) >= 0;
if(replaced){
newStr = newStr.replace(regex, '!');
}
If you don't want that either, you can abuse the replace callback to achieve that in a single pass:
var replaced = false;
var newStr = str.replace(/i/g, function(token){replaced = true; return '!';});
As a workaround you can implement your own callback function that will set a flag and do the replacement. The replacement argument of replace can accept functions.
Comparing the before and after strings is the easiest way to check if it did anything, there's no intrinsic support in String.replace().
[contrived example of how '==' might fail deleted because it was wrong]
Javascript replace is defected by design. Why? It has no compatibility with string replacement in callback.
For example:
"ab".replace(/(a)(b)/, "$1$2")
> "ab"
We want to verify that replace is done in single pass. I was imagine something like:
"ab".replace(/(a)(b)/, "$1$2", function replacing() { console.log('ok'); })
> "ab"
Real variant:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
return "$1$2";
})
> ok
> "$1$2"
But function replacing is designed to receive $0, $1, $2, offset, string and we have to fight with replacement "$1$2". The solution is:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
// arguments are $0, $1, ..., offset, string
return Array.from(arguments).slice(1, -2)
.reduce(function (pattern, match, index) {
// '$1' from strings like '$11 $12' shouldn't be replaced.
return pattern.replace(
new RegExp("\\$" + (index + 1) + "(?=[^\\d]|$)", "g"),
match
);
}, "$1$2");
});
> ok
> "ab"
This solution is not perfect. String replacement itself has its own WATs. For example:
"a".replace(/(a)/, "$01")
> "a"
"a".replace(/(a)/, "$001")
> "$001"
If you want to care about compatibility you have to read spec and implement all its craziness.
If your replace has a different length from the searched text, you can check the length of the string before and after. I know, this is a partial response, valid only on a subset of the problem.
OR
You can do a search. If the search is successfull you do a replace on the substring starting with the found index and then recompose the string. This could be slower because you are generating 3 strings instead of 2.
var test = "Hellllo";
var index = test.search(/ll/);
if (index >= 0) {
test = test.substr(0, index - 1) + test.substr(index).replace(/ll/g, "tt");
}
alert(test);
While this will require multiple operations, using .test() may suffice:
const regex = /foo/;
const yourString = 'foo bar';
if (regex.test(yourString)) {
console.log('yourString contains regex');
// Go ahead and do whatever else you'd like.
}
The test() method executes a search for a match between a regular expression and a specified string. Returns true or false.
With indexOf you can check wether a string contains another string.
Seems like you might want to use that.
have a look at string.match() or string.search()
After doing any RegExp method, read RegExp.lastMatch property:
/^$/.test(''); //Clear RegExp.lastMatch first, Its value will be ''
'abcd'.replace(/bc/,'12');
if(RegExp.lastMatch !== '')
console.log('has been replaced');
else
console.log('not replaced');

Categories