indexOf is not working in JavaScript - javascript

I am checking an index Of string in JAVASCRIPT. and this is coming as false. where as the value does belong to it as below :
if(idOfControl.indexOf(idOfButton)) == is giving false for the below values.
idOfControl = "dlInventory_btnEditComment_0"
idOfButton = "dlInventory_btnEditComment"
But if I run idOfControl.replace(idOfButton, ""); It is working and replacing the text.
Any reason for this?

indexOf can also return 0, in the event of your string being found at the position 0. 0 evaluates to false. Try:
if(idOfControl.indexOf(idOfButton) > -1)
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf

There are these three big options:
indexOf > -1
The result of indexOf can be 0 meaning that the string was found at the beginning of the string. When string is not found, the return value is -1, therefore:
if (idOfControl.indexOf(idOfButton) > -1) {
// Do something
}
Which can be nicer written as #paxdiablo commented:
if (idOfControl.indexOf(idOfButton) >= 0) {
// Do something
}
via regex
You can use a very simple regular expression to test your match.
var idOfControl = "dlInventory_btnEditComment_0"
var control = /dlInventory_btnEditComment/;
if (idOfControl.test(control)) {
// do something
}
This approach can be enhanced to capture the last number of your string (if you need it)
var idOfControl = "dlInventory_btnEditComment_0"
var control = /dlInventory_btnEditComment_(\d+)/;
var match = control.exec(idOfControl);
if (match) {
alert('the number found is: ' + match[1]);
}
You can try it out here: http://jsfiddle.net/4Z9UC/
via indexOf in a hacky way
This uses a bitwise operator to return a truthy value when the position is !=-1 (In two's complement notation, -1 is internally represented as 111...111, and its inversion is 000...000 which is 0, i.e. a falsy value). It is in fact more efficient than the >-1 option, but it is harder to read and to understand. (EDIT: this became so popular that you can say it is a standard)
if (~idOfControl.indexOf(idOfButton)) {
// do something
}

Related

Javascript find and match last item of the string

I am trying tor write this function that Check if a string (first argument, str) ends with the given target string (second argument, target). I have used this code but it seems not to work. How can i tweak it?
function confirmEnding(str, target) {
var last = str.substring(-1);
var last2 = target.substring(-1);
if (last == last2) return true;
else if (last !== last2) return false;
}
confirmEnding("Walking on water and developing software from a specification
are easy if both are frozen", "specification") )/*should return "false".
confirmEnding("Bastian", "n") should return true.
confirmEnding("Connor", "n") should return false.
confirmEnding("Walking on water and developing software from a specification
are easy if both are frozen", "specification") should return false.
confirmEnding("He has to give me a new name", "name") should return true.
confirmEnding("Open sesame", "same") should return true.
confirmEnding("Open sesame", "pen") should return false.
confirmEnding("If you want to save our world, you must hurry. We dont know
how much longer we can withstand the nothing", "mountain") should return
false.
Do not use the built-in method .endsWith() to solve the challenge.*/
In order to pass all of the tests with the desired return values, the function should not be comparing the last character of the string, but rather the entire string, target to the corresponding end substring of str. You need the length of target to find the correct starting index for the corresponding substring in str as follows:
function confirmEnding (str, target) {
return str.substr(-(target.length)) === target
}
Your code is comparing the entire strings. See substring() documentation below. -1 is defaulting to 0 thus returning the substring starting at index 0 and returning the rest of the string (the entire string) since no end index is given. .
"If either argument is less than 0 or is NaN, it is treated as if it
were 0."
You can use the substr() method instead of substring() if you want to use negative indices. substr() recognizes negative index values instead of defaulting to 0.
"If start is negative, substr() uses it as a character index from the
end of the string."
You can use the length of target and subtract it from the length of str to get the correct substring for comparison. This will return all of the characters from this index to the end of the string as in str.length - target.lengththough you only really need target.length to make the comparison using negative indices.
Using substring():
function confirmEnding (str, target) {
var last = str.substring(str.length-(target.length));
if (last == target ) return true;
else return false;
}
Using substr():
function confirmEnding (str, target) {
var last = str.substr(-(target.length));
if (last == target ) return true;
else return false;
}
or a cleaner/alternate implementation:
function confirmEnding (str, target) {
return str.substr(-(target.length) === target)
}
substr() documentation
substring() documentation
After seeing the ongoing confusion over this case (abbreviated for readability):
confirmEnding(
"Walking on water...both are frozen",
"specification"
); // Should return false (why not true?)
and also this interesting note:
/* Do not use the built-in method .endsWith() to solve the challenge. */
I have a hunch about what may have happened.
Double-check the instructions for this question. Are you sure you're supposed to test if the last character of each string is the same? It sounds like you are supposed to test if the src string ends with the entire target string.
After all, that is what the .endsWith() method does. And it explains the mystery of the test case above.
The MDN documentation for .endsWith() doesn't describe the method very well, but the examples it gives make it clear.
With that understanding, you can probably now write the code. I'm not going to write it for you, but I will drop some hints below. I added some code for your tests so that they not only log the result, but also whether they return the desired result. (In the version as written here, all the tests will fail.)
// Return true if str ends with target, false if it does not
function confirmEnding( str, target ) {
// You can do this in a single return statement
// with one === comparison in it. The .slice()
// method will help you here, and you only need
// to pass a single argument into it.
// You don't need any if statements, intermediate
// variables, or anything fancy.
// There are several other ways to do it too, including
// the approach shown on the MDN page.
}
function testEnding( str, target, desired ) {
var result = confirmEnding( str, target );
console.log(
'"' + str + '"',
'"' + target + '"',
'returns', result,
result === desired ? 'Good' : 'WRONG!'
);
}
testEnding( "Bastian", "n", true );
testEnding( "Connor", "n", false );
testEnding( "Walking on water and developing software from a specification are easy if both are frozen", "specification", false );
testEnding( "He has to give me a new name", "name", true );
testEnding( "Open sesame", "same", true );
testEnding( "Open sesame", "pen", false );
testEnding( "If you want to save our world, you must hurry ); We dont know how much longer we can withstand the nothing", "mountain", false );
You can use this function:
function confirmEnding(a, b) {
var l1 = a[a.length - 1];
var l2 = b[b.length - 1];
return l1 === l2;
}
Your error is that you're using substring. Try str.substr instead of substring
function confirmEnding (str, target) {
return str.substr(-1) == target.substr(-1);
}
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"));
const a = "Walking on water and developing software from a specification are easy if both are frozen",
b = "specification";
// your function
const equalLastLetter = (a, b) => a.substr(-1) === b.substr(-1);
console.log(equalLastLetter(a, b))
How about this?
function confirmEnding (str, target) {
var last = str.charAt(str.length-1);
var last2 = target.charAt(target.length-1);
return (last == last2);
}
You can use chatAt()
function confirmEnding (str, target) {
var last = str.charAt(str.length -1);
var last2 = target.charAt(target.length -1);
return last === last2 ;
}
Why have to check if last words are same so:
const confirmEnding = (str, target) => new RegExp(`${target}$`, '').test(str)
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"))
console.log(confirmEnding("Bastian", "n"))
console.log(confirmEnding("Connor", "n"))
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"))
console.log(confirmEnding("He has to give me a new name", "name"))
console.log(confirmEnding("Open sesame", "same"))
console.log(confirmEnding("Open sesame", "pen"))
console.log(confirmEnding("If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing", "mountain"))
Simplest way:
const confirmEnding = (_str, _target) => _str.charAt(_str.length - 1) === _target.charAt(_target.length - 1);
https://jsfiddle.net/pablodarde/hsdgjmzw/

unexpected results in evaluation of chains logical expressions javascript

I am writing a program to identify special numbers according to the criteria laid out in this code wars kata:
http://www.codewars.com/kata/catching-car-mileage-numbers
Here is a link to my full code and tests:
http://www.codeshare.io/UeXhW
I have unit tested my functions which test for each of the special number conditions and they appear to be working as expected. However, I have a function:
function allTests(number, awesomePhrases){
var num = number.toString().split('');
// if any criteria is met and the number is >99 return true
return number > 99 && (allZeros(num) || sameDigits(num) || incrementing(num) || decrementing(num) || palindrome(number) || matchPhrase(number, awesomePhrases)) ? true : false;
}
which determines if any of the criteria of being a special number is met and that's not working as expected. For example, when I tested the allZeros() function on 7000 it returned true, but alltests(7000) is returning false. Is there something about how chains of logical expressions are evaluated that I don't understand or is the problem something else?
I have looked at W3schools and MDN to try and diagnose the problem.
Change all your !== to != will do.
False results as long as allTests() executes with a second argument even it it's the empty string, as follows:
allTests(7000,"");
If the function is called with just one argument, i.e. the number, expect this error:
Uncaught TypeError: Cannot read property 'length' of undefined
The error message refers to one of the functions in the logic chain, namely matchPhrase() which expects two parameters: number and awesomePhrases. If instead of providing an empty string, you use null, you'll also get the same error message.
JavaScript doesn't support the concept of default parameters -- at least not in a way that one might expect; the parameters default to undefined. But there is a way to work around this hurdle and improve the code so that one may avoid this needless error. Just change matchPhrase() as follows:
function matchPhrase(number, awesomePhrases){
awesomePhrases = typeof awesomePhrases !== 'undefined' ? awesomePhrases : "";
for(var i = 0, max=awesomePhrases.length; i < max; i++){
if(number == awesomePhrases[i]){
return true;
}
}
return false;
}
The first statement accepts the second argument's value as long as it is not the undefined value; if so, then the variable gets set to the empty string. (Source for technique: here).
To make the code more readily comprehensible, I suggest rewriting allTests() as follows, so that the code follows a more explicit self-documenting style:
function allTests(number, awesomePhrases){
var arrDigits = number.toString().split('');
// if any criteria is met and the number is >99 return true
return number > 99 && (allZeros( arrDigits ) || sameDigits( arrDigits ) || incrementing( arrDigits ) || decrementing( arrDigits) || palindrome(number) || matchPhrase(number, awesomePhrases)) ? true : false;
}
This function takes a number and uses its toString() method to convert the number to a string. The resulting string which is not visible will split itself on the empty string so that the result of arrDigits is an array of numerical strings, each one consisting of just one digit. This is the point of origin for the ensuing problem with allZeros() which compares a stringified digit with a number.
Incidentally, in the function allTests() there is an awfully lengthy ternary expression. The syntax is fine, but you might wish to rewrite the code as follows:
function getCriteriaStatus(arrDigits,number,awesomePhrases) {
var criteria = new Array();
criteria[0] = allZeros( arrDigits );
criteria[1] = sameDigits( arrDigits );
criteria[2] = incrementing( arrDigits );
criteria[3] = decrementing( arrDigits);
criteria[4] = palindrome(number);
criteria[5] = matchPhrase(number, awesomePhrases);
var retval = false;
for (var i=0, max=6; i < max; i++) {
if ( criteria[i] == true ) {
retval = true;
break;
}
}
return retval;
}
function allTests(number, awesomePhrases){
var arrDigits = number.toString().split('');
var criteria_met = getCriteriaStatus(arrDigits,number,awesomePhrases);
return (number > 99 && criteria_met);
}
To obtain the desired true result from allTests() when it invokes allZeros(), rather than complicate the code by using parseInt(), I suggest rewriting allZeros() and any other functions containing code that compares a numerical string value with a number by changing from the identity operator to the equality operator. The change involves merely replacing === with == as well as replacing !== with !=. The code that compares values of the same data type, using the identity operators, those operators may, and probably should, remain unchanged. (See here).

Check a string that MUST contain another string [duplicate]

This question already has answers here:
How to check whether a string contains a substring in JavaScript?
(3 answers)
Closed 9 years ago.
I want to check if string b is completely contained in string a.
I tried:
var a = "helloworld";
var b = "wold";
if(a.indexOf(b)) {
document.write('yes');
} else {
document.write('no');
}
The output is yes, it is not my expected output, because string b(wold) is not completely contained in string a(helloworld) --- wold v.s. world
Any suggestion to check the string?
Read the documentation: MDC String.indexOf :)
indexOf returns the index the match was found. This may be 0 (which means "found at the beginning of string") and 0 is a falsy value.
indexOf will return -1 if the needle was not found (and -1 is a truthy value). Thus the logic on the test needs to be adjusted to work using these return codes. String found (at beginning or elsewhere): index >= 0 or index > -1 or index != -1; String not found: index < 0 or index == -1.
Happy coding.
You need to use if(a.indexOf(b) > -1) instead. indexOf returns -1 when it can't find a string.
.indexOf returns -1 if no match was found, which is a truthy value. You'll need to check more explicitly:
if (a.indexOf(b) != -1)
That's because indexOf returns -1 if a value is not found:
if(a.indexOf(b) != -1) {
you may want to use this
if(a.indexOf(b) != -1)
You need to test if the result is -1. -1 indicates no match, but evaluates to true in a boolean sense.
var a = "helloworld";
var b = "wold";
if(a.indexOf(b) > -1) {
document.write('yes');
} else {
document.write('no');
}

Javascript string/integer comparisons

I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);

Check if string contains only digits

I want to check if a string contains only digits. I used this:
var isANumber = isNaN(theValue) === false;
if (isANumber){
..
}
But realized that it also allows + and -. Basically, I want to make sure an input contains ONLY digits and no other characters. Since +100 and -5 are both numbers, isNaN() is not the right way to go.
Perhaps a regexp is what I need? Any tips?
how about
let isnum = /^\d+$/.test(val);
string.match(/^[0-9]+$/) != null;
String.prototype.isNumber = function(){return /^\d+$/.test(this);}
console.log("123123".isNumber()); // outputs true
console.log("+12".isNumber()); // outputs false
If you want to even support for float values (Dot separated values) then you can use this expression :
var isNumber = /^\d+\.\d+$/.test(value);
Here's another interesting, readable way to check if a string contains only digits.
This method works by splitting the string into an array using the spread operator, and then uses the every() method to test whether all elements (characters) in the array are included in the string of digits '0123456789':
const digits_only = string => [...string].every(c => '0123456789'.includes(c));
console.log(digits_only('123')); // true
console.log(digits_only('+123')); // false
console.log(digits_only('-123')); // false
console.log(digits_only('123.')); // false
console.log(digits_only('.123')); // false
console.log(digits_only('123.0')); // false
console.log(digits_only('0.123')); // false
console.log(digits_only('Hello, world!')); // false
Here is a solution without using regular expressions:
function onlyDigits(s) {
for (let i = s.length - 1; i >= 0; i--) {
const d = s.charCodeAt(i);
if (d < 48 || d > 57) return false
}
return true
}
where 48 and 57 are the char codes for "0" and "9", respectively.
This is what you want
function isANumber(str){
return !/\D/.test(str);
}
in case you need integer and float at same validation
/^\d+\.\d+$|^\d+$/.test(val)
function isNumeric(x) {
return parseFloat(x).toString() === x.toString();
}
Though this will return false on strings with leading or trailing zeroes.
Well, you can use the following regex:
^\d+$
if you want to include float values also you can use the following code
theValue=$('#balanceinput').val();
var isnum1 = /^\d*\.?\d+$/.test(theValue);
var isnum2 = /^\d*\.?\d+$/.test(theValue.split("").reverse().join(""));
alert(isnum1+' '+isnum2);
this will test for only digits and digits separated with '.' the first test will cover values such as 0.1 and 0 but also .1 ,
it will not allow 0. so the solution that I propose is to reverse theValue so .1 will be 1. then the same regular expression will not allow it .
example :
theValue=3.4; //isnum1=true , isnum2=true
theValue=.4; //isnum1=true , isnum2=false
theValue=3.; //isnum1=flase , isnum2=true
Here's a Solution without using regex
const isdigit=(value)=>{
const val=Number(value)?true:false
console.log(val);
return val
}
isdigit("10")//true
isdigit("any String")//false
If you use jQuery:
$.isNumeric('1234'); // true
$.isNumeric('1ab4'); // false
If you want to leave room for . you can try the below regex.
/[^0-9.]/g
c="123".match(/\D/) == null #true
c="a12".match(/\D/) == null #false
If a string contains only digits it will return null

Categories

Resources