JavaScript search() method equates to zero in two ways, leading to problems - javascript

If you take a piece of code like this:
var string = "javascript";
var search = string.search("");
console.log(search);
and then you take this piece of code:
var string = "javascript";
var search = string.search("j");
console.log(search);
both pieces of code evaluate to 0. It's fairly annoying since I would imagine it should amount to -1 since there is no match, nothing and the. This is a problem in a script I am trying to write because these both evaluate to the exact same number even though they aren't the same value and this is making me move all my data in my .json file over by one space from this:
"heman",
"candy",
"powerpuffgirls",
"oranges"
to this:
" heman",
" candy",
" powerpuffgirls",
" oranges"
because when I test for a match from the input field the user enters to the .json data I have no way of evaluating whether the data was blank or one matching character was entered (since the javascript search method evaluates both as the same amount '0'). This incapacity of javascript to know the difference between a 'nothing' and a 'single matching char' moved along at zero index (since it's a single matching char) has forced me to move all of .json data over one space.
This feels...wrong to do, like not good practice. It's a solution but it seems like a lame one. Does anybody know any work arounds for a problem like this? Seems like a pretty simple common problem. Is there some way through this, perhaps with regular expressions or something?

Remember this:
Always, whatever be the value of the variable string (including empty string)
string.search("") = 0
So, check for length of the string!
if (string.length == 0) // Empty string

var search = query.length === 0 ? -1 : string.search(query);

Related

replacing every second occurrence of a letter with a different letter or simbol

This pertains to any language that you think will work. Is there a way to change the look of a text input to replace every second space (space as in when the space bar is hit it makes a space) i need to a way almost like a counter that once it counts 2 spaces then it replaces that 2nd space to a letter or symbol. if someone could help me with this it would be amazing and the purpose is just to change the way the text looks in this way functionality does not matter as long as it reads like normal text. ( if it helps it would be every odd number of spaces gets changed.)
for example i want to be able to copy and paste something in like this> "i went down to the sea to pick up many sticks for my collection"
and have it return something like this
i%went down%to the%sea to%pick up%many sticks%for my%collection
the end goal is for the symbol to be a different color so it stands out from the text so if that would be possible that would be amazing.
I chose javascript, but there are multiple languages that you could choose and there are multiple ways to accomplish this. This is the train of thought that you should use when solving this problem:
Determine the characters that you want to replace
Determine the character that you want to replace it with
Since we don't want to replace every single one, what is the pattern/frequency that you want to replace found occurrences with.
For the 3rd question, you've said that you want to replace every other occurrence, so we need to keep track of the count of occurrences. And replace it when occurrence modulo 2 = 1. This says replace every odd occurrence.
I chose to use regex to find all the spaces in the sentence, have a counter n and increment the counter every time I find a space.
This leaves us with the following code:
const input = "i went down to the sea to pick up many sticks for my collection";
let n = 0;
const output = input.replace(/\s/g, (m, i, og) => {
return (n++ % 2) ? m : '%';
});
// output = "i%went down%to the%sea to%pick up%many sticks%for my%collection"
Also please take a look at String.prototype.replace() so you can learn about using regex, and to learn about what the function does. This will help you learn and solve similar problems by yourself in the future.
you can use a boolean variable to count odd and even spaces and string.prototyoe.replace with a callback function:
var str = 'i went down to the sea to pick up many sticks for my collection';
var odd = true;
str = str.replace(/\s/gi, (spaceChar)=>{
odd = !odd;
return !odd ? spaceChar : '%'; // this is what you wrote (every second)
// return odd ? spaceChar : '%'; // this is what your expected result shows (every second starting with the first occurence)
});

How to find any of the specific characters exists in a string

Im looking for a solution to search the existence of given characters in a string. That means if any of the given characters present in a string, it should return true.
Now am doing it with arrays and loops. But honestly I feel its not a good way. So is there is any easiest way without array or loop?
var special = ['$', '%', '#'];
var mystring = ' using it to replace VLOOKUP entirely.$ But there are still a few lookups that you are not sure how to perform. Most importantly, you would like to be able to look up a value based on multiple criteria within separate columns.';
var exists = false;
$.each(special, function(index, item) {
if (mystring.indexOf(item) >= 0) {
exists = true;
}
});
console.info(exists);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
try with regex
var patt = /[$%#]/;
console.log(patt.test("using it to replace VLOOKUP entirely.$ But there are still a few lookups that you are not sure how to perform. Most importantly, you would like to be able to look up a value based on multiple criteria within separate columns."));
Be aware that [x] in regEx is for single characters only.
If you say wanted to search for say replace, it's going to look for anything with 'r,e,p,l,a,c' in the string.
Another thing to be aware of with regEx is escaping. Using a simple escape regEx found here -> Is there a RegExp.escape function in Javascript? I've made a more generic find in string.
Of course you asked given characters in a string, so this is more of an addenum answer for anyone finding this post on SO. As looking at your original question of an array of strings, it might be easy for people to think that's what you could just pass to the regEx. IOW: your questions wasn't how can I find out if $, %, # exist in a string.
var mystring = ' using it to replace VLOOKUP entirely.$ But there are still a few lookups that you are not sure how to perform. Most importantly, you would like to be able to look up a value based on multiple criteria within separate columns.';
function makeStrSearchRegEx(findlist) {
return new RegExp('('+findlist.map(
s=>s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|')+')');
}
var re = makeStrSearchRegEx(['$', '%', '#', 'VLOOKUP']);
console.log(re.test(mystring)); //true
console.log(re.test('...VLOOKUP..')); //true
console.log(re.test('...LOOKUP..')); //false
The best way is to use regular expressions. You can read more about it here.
In your case you should do something like this:
const specialCharacters = /[$%#]/;
const myString = ' using it to replace VLOOKUP entirely.$ But there are still a few lookups that you are not sure how to perform. Most importantly, you would like to be able to look up a value based on multiple criteria within separate columns.';
if(specialCharacters.test(myString)) {
console.info("Exists...");
}
Please, note, that it is good approach to store regular expressions in a variable to prevent creating of regular expression (which is not the fastest operation) each time you use it.

Get id from url

I have the following example url: #/reports/12/expense/11.
I need to get the id just after the reports -> 12. What I am asking here is the most suitable way to do this. I can search for reports in the url and get the content just after that ... but what if in some moment I decide to change the url, I will have to change my algorythm.
What do You think is the best way here. Some code examples will be also very helpfull.
It's hard to write code that is future-proof since it's hard to predict the crazy things we might do in the future!
However, if we assume that the id will always be the string of consecutive digits in the URL then you could simply look for that:
function getReportId(url) {
var match = url.match(/\d+/);
return (match) ? Number(match[0]) : null;
}
getReportId('#/reports/12/expense/11'); // => 12
getReportId('/some/new/url/report/12'); // => 12
You should use a regular expression to find the number inside the string. Passing the regular expression to the string's .match() method will return an array containing the matches based on the regular expression. In this case, the item of the returned array that you're interested in will be at the index of 1, assuming that the number will always be after reports/:
var text = "#/reports/12/expense/11";
var id = text.match(/reports\/(\d+)/);
alert(id[1]);
\d+ here means that you're looking for at least one number followed by zero to an infinite amount of numbers.
var text = "#/reports/12/expense/11";
var id = text.match("#/[a-zA-Z]*/([0-9]*)/[a-zA-Z]*/")
console.log(id[1])
Regex explanation:
#/ matches the characters #/ literally
[a-zA-Z]* - matches a word
/ matches the character / literally
1st Capturing group - ([0-9]*) - this matches a number.
[a-zA-Z]* - matches a word
/ matches the character / literally
Regular expressions can be tricky (add expensive). So usually if you can efficiently do the same thing without them you should. Looking at your URL format you would probably want to put at least a few constraints on it otherwise the problem will be very complex. For instance, you probably want to assume the value will always appear directly after the key so in your sample report=12 and expense=11, but report and expense could be switched (ex. expense/11/report/12) and you would get the same result.
I would just use string split:
var parts = url.split("/");
for(var i = 0; i < parts.length; i++) {
if(parts[i] === "report"){
this.reportValue = parts[i+1];
i+=2;
}
if(parts[i] === "expense"){
this.expenseValue = parts[i+1];
i+=2;
}
}
So this way your key/value parts can appear anywhere in the array
Note: you will also want to check that i+1 is in the range of the parts array. But that would just make this sample code ugly and it is pretty easy to add in. Depending on what values you are expecting (or not expecting) you might also want to check that values are numbers using isNaN

Regular Expression with multiple words (in any order) without repeat

I'm trying to execute a search of sorts (using JavaScript) on a list of strings. Each string in the list has multiple words.
A search query may also include multiple words, but the ordering of the words should not matter.
For example, on the string "This is a random string", the query "trin and is" should match. However, these terms cannot overlap. For example, "random random" as a query on the same string should not match.
I'm going to be sorting the results based on relevance, but I should have no problem doing that myself, I just can't figure out how to build up the regular expression(s). Any ideas?
The query trin and is becomes the following regular expression:
/trin.*(?:and.*is|is.*and)|and.*(?:trin.*is|is.*trin)|is.*(?:trin.*and|and.*trin)/
In other words, don't use regular expressions for this.
It probably isn't a good idea to do this with just a regular expression. A (pure, computer science) regular expression "can't count". The only "memory" it has at any point is the state of the DFA. To match multiple words in any order without repeat you'd need on the order of 2^n states. So probably a really horrible regex.
(Aside: I mention "pure, computer science" regular expressions because most implementations are actually an extension, and let you do things that are non-regular. I'm not aware of any extensions, certainly none in JavaScript, that make doing what you want to do any less painless with a single pattern.)
A better approach would be to keep a dictionary (Object, in JavaScript) that maps from words to counts. Initialize it to your set of words with the appropriate counts for each. You can use a regular expression to match words, and then for each word you find, decrement the corresponding entry in the dictionary. If the dictionary contains any non-0 values at the end, or if somewhere a long the way you try to over-decrement a value (or decrement one that doesn't exist), then you have a failed match.
I'm totally not sure if I get you right there, so I'll just post my suggestion for it.
var query = "trin and is",
target = "This is a random string",
search = { },
matches = 0;
query.split( /\s+/ ).forEach(function( word ) {
search[ word ] = true;
});
Object.keys( search ).forEach(function( word ) {
matches += +new RegExp( word ).test( target );
});
// do something useful with "matches" for the query, should be "3"
alert( matches );
So, the variable matches will contain the number of unique matches for the query. The first split-loop just makes sure that no "doubles" are counted since we would overwrite our search object. The second loop checks for the individuals words within the target string and uses the nifty + to cast the result (either true or false) into a number, hence, +1 on a match or +0.
I was looking for a solution to this issue and none of the solutions presented here was good enough, so this is what I came up with:
function filterMatch(itemStr, keyword){
var words = keyword.split(' '), i = 0, w, reg;
for(; w = words[i++] ;){
reg = new RegExp(w, 'ig');
if (reg.test(itemStr) === false) return false; // word not found
itemStr = itemStr.replace(reg, ''); // remove matched word from original string
}
return true;
}
// test
filterMatch('This is a random string', 'trin and is'); // true
filterMatch('This is a random string', 'trin not is'); // false

Selenium adding weird characters to the end of javascript in a form field

I'm trying to set up a field to prepopulate with a unique set of characters, so that i can automatically generate test accounts. Because of the way the system is set up, the name field must be unique, and must not include numerical characters.
I put together this selenium code, and it works 99% of the way, but leaves extra garbage characters at the end of the good code.
javascript{stringtime='';
nowtime=new Date().getTime().toString();
for ( var i in nowtime )
{ stringtime+=String.fromCharCode(parseInt(nowtime[i])+65 ); };
'test' + stringtime + '\0'}
Result:
testBCEBBJCBFBBAI + a bunch of characters that won't copy into here. They look like 4 zeros in a box.
Thanks in advance for the help.
Excluding the '\0' character at the end, which shows up at a ?, and within Selenium, I think it's javascript engine is having trouble processing the for(var i in nowtime).
Try it like this:
javascript{
stringtime= '';
nowtime=new Date().getTime().toString();
for(var i = 0; i < nowtime.length; i++){
stringtime += String.fromCharCode(parseInt(nowtime[i])+65);
}
stringtime;
}
Those characters are ones that are outside the standard ASCII that your font can't reproduce. Those numbers signify which character it is. If its 4 zeros, its that \0 char you are putting on at the end. I don't know the language, but it doesn't look like you need that.
Also your random number generator is a bit flawed. Have a look here:
http://www.mediacollege.com/internet/javascript/number/random.html

Categories