I have the following snippet of code :
return (AllowableCharacters.indexOf(String.fromCharCode(k)) != -1);
Now, I don't quite get the usage of -1 in this script.
The way the script reads is as follows:
first String.fromCharCode(k) != -1 is executed (k is a key code , I am dynamically getting from some other script).
Then I get the indexof(String.fromCharCode(k) != -1) from AllowableCharacters.
Which is a string something like this:
AllowableCharacters = "abc" ;
I also understand that if the indexof can't find a value in the above string it return -1.
Coming back to my question, however, why the -1 in the script?
EDIT ::
To make my question simpler , how would you read the following line :
String.fromCharCode(k))!=-1
in simple plain english .
EDIT 2::
ok so i just read guffa's answer and made a random script to check , heres the script :
var store = "abcdefgpS";
function check_index(){
console.log(store.indexOf(String.fromCharCode(83)));
};
in the above function the !-1 is excluded , so on console.log , if a match is found we get the indexOf where the character was found and well if a match is not found we get -1 .
NOW , now thats not what we want , what we want is a "tell me if the value is there"(return true) or "tell me if the value is not there"(return false).
so what we do is we change the above script to :
var store = "abcdefgpS";
function check_index(){
console.log(store.indexOf(String.fromCharCode(83)) !-1);
};
which, gives ur true or false values .
now how does :
return (store.indexOf(String.fromCharCode(83)) !-1)
read as :
if (store.indexOf(String.fromCharCode(83)) !-1){
return true;
}else { return false; }
I don't see the if statement in .
return (store.indexOf(String.fromCharCode(83)) !-1);
Thank you,
Alexander
This is a condition that validates whether or not a character is allowed. It will return a boolean (the result of the comparison).
Let's break it down.
First, we get a string from a char code with String.fromCharCode. Presumably we've received this from an input event of some kind.
Next, we get the index of this resulting single-character string in AllowableCharacters using indexOf.
Finally, we test if that result is -1. A test evaluates to a boolean value, and it can be returned from a function just like any other value. A value of -1 indicates that the character is not allowed, so we use != to determine if the character is valid.
You got the order of execution wrong.
First this expression is evaluated: String.fromCharCode(k).
Lets assume that the result is the string "b". That is used in the expression: AllowableCharacters.indexOf("b").
Lets assume that the characer is found at the second character in the string, which has index 1, so the result is 1. That is used in the expression 1 != -1.
As the 1 is not equal to -1, the result is true, which is returned.
In short, the -1 is compared with the result from the indexOf method, as the methods returns -1 when it doesn't find anything.
It's the comparison operator != that causes the value to be true or false. It compares the values, and the result depends on whether they are equal or not. An if statement isn't needed to turn the result into true or false, that's already the value of the comparison expression.
Sometimes you see code like:
if (AllowableCharacters.indexOf(String.fromCharCode(k)) != -1) {
return true;
} else {
return false;
}
The if statement is superflous in cases like that. The expression in the if statement is already true or false, so it can be returned directly:
return AllowableCharacters.indexOf(String.fromCharCode(k)) != -1;
Related
can you explain how works letters[pass[i]] = (letters[pass[i]] || 0) + 1?
This line adds letters from pass to the letters object as keys and it's number of occurs in the value.
So, for example, for pass = "aabbc" you'll have letters equal to
{
"a":2,
"b":2,
"c":1
}
The operator on the right ((letters[pass[i]] || 0) + 1) can be splitted to two:
letters[pass[i]] || 0 checks if letters has key of value pass[i], if so the expression will have it's value, if not then we will get value after || - in this case 0. To value of this expression we add always 1.
Also, we could convert this one line to something like this:
if(letters[pass[i]]) {
letters[pass[i]]++;
} else {
letters[pass[i]] = 1;
}
About the || operator in value assignment you can read more for example here
Let's start from the inside out, like JavaScript does. :-)
(letters[pass[i]] || 0) + 1
That:
Starts with pass[i] which gets the letter for index i from pass (which appears to be a string)
Then tries to get the value for a property with that name from letters (letters[pass[i]]). It will either get a number that it's put there before or, if there is no property for that letter (yet), it'll get the value undefined.
It uses that value (a number or undefined) with (the value) || 0. The || operator works fairly specially in JavaScript: It evaluates its left-hand operand and, if that value is truthy, takes that value as its result; otherwise, it evaluates its right-hand operand and takes that value as its result. undefined is a falsy value, so undefined || 0 is 0. This is to handle the first time a letter is seen.
It adds 1 to the result it got from ||.
Basically, that's adding one to the value of the property for the letter on letters, allowing for never having seen that letter before via ||.
Then it stores the result back to the property.
I've been studying JavaScript for a couple months, and I have some questions.
Say we have some if statements like this:
if (something)
if (!something)
From what I have looked up, the first statement checks whether something evaluates to true, whereas the second one checks for whether the condition is not true(I recall reading the ! coerces it into boolean and then 'inverses' it).
However, I'd like to know what are these statements' direct equivalents when not "shortened". I'd like to understand code like this more in depth before really using it.
Is if (something) the same as if (something == true)? Or even if (something === true)?
And what would be the "non-shortened" (for my lack of a better term) direct equivalent of if (!something)?
Thank you for any help.
Part 1:
When we use if(something) javascript will check if it is a 'Truthy' or 'Falsy' value.
So if we say
if(1) {
alert("Yes, it's true...");
}
javscript will check if 1 is a "truthy" value and it is.
Everything that is not a falsy value is truthy by extension.
Falsy values are:
0, 0n, null, undefined, false, NaN, and the empty string “”.
So if we directly put any of the above into a parenthesis it will return false.
e.g. if (null) ... the if clause won't be executed because null is falsy.
Part 2:
When we use if(something == true), we check if one value is equal to another value. If the types are not the same, since we're using == coercion will happen.
What is this about 'coercion'?
If we say if('1' == 1) this will execute the if clause as it returns true. Javascript will convert 1(number) to '1'(string) in this case.
If we want to be strict and say "I only want true if they're both numbers, I don't care if 1 is a string" then we use
if(1 === '1') and this will not execute the if clause(because the condition returns false).
So if we say if(false == false) this will return true because false is equal to false, and the if clause will be executed.
Note the difference if we said if(false) or if('') the if statement will not be executed.
Next, if we want to use negation, we have to put the ! in front of the boolean we're negating, regardless of whether it's part of an if condition or... There is no way around it.
However, there is a shorter version of this:
var a = 3;
var b = 2;
if(a===b) {
alert('A is equal to B');
} else {
alert('B is not equal to A');
}
This is considered shorter(ternary operator):
Note that if we want to use more than one statement, we should use the if else
a = 3;
b = 2;
a===b ? alert('A is equal to B') : alert('B is not equal to A');
str.indexOf(searchValue[, fromIndex])
The index of the first occurrence of searchValue, or -1 if not found.
- MDN web docs
Why was -1 chosen to be the returned value by .indexOf if it doesn't find a match in the array?
console.log([].indexOf()) // -> -1
Would it not be more suitable to have 0 instead? It would make sense because there are indeed 0 matching element. And this way we could have used it directly in a conditional statement, for example:
if( Array.indexOf(String) ) { ... }
Instead of
if( Array.indexOf(String) !== -1 ) { ... }
Why is that? Any particular reason? I've seen the same in Java, C++ and C. Is this because of how the native function was designed?
Would it not be more suitable to have 0 instead?
No. Indexes start from zero.
var str = "ABC";
console.log(str[0]);
console.log(str.indexOf("A"));
(The same is true of arrays, which you used for your examples despite quoting the documentation for strings).
Well. It's pretty straight forward as to why. indexOf returns the position of an element not if it exists or not. Plus all ( 99% ) programming languages are 0 indexed, or better say strings and arrays are 0 indexed which means that the first element is at position 0.
Think of position as the offset of an element from the start of the array. So the distance/offset of the first element from the start of the array is, well, 0 :)
Maybe you are looking for includes() which checks if an element is inside an array.
const arr=[1,2,3]
// classic
if (!arr.includes(4)) {
console.log('4 does not exist (classic)')
}
// or short circuit
!arr.includes(4) && console.log('4 does not exist (short circuit)')
// conditional (ternary) operator
!arr.includes(4) ? console.log('4 does not exist (ternary)') : ""
Observation
Also you shouldn't use indexOf() as a boolean condition because for example
let arr=['a','b','c']
arr.indexOf('a') ? console.log('true') : console.log('false')
In the above example, indexOf(a) returns it's position 0. In a boolean condition 0 is treated as false by javaScript. So it would not give you the expected result.
Everyone else is saying the same thing, but let me try another wording of the answer.
In Javascript arrays are indexed starting with element 0. So if the string qas found at the begining the valid return value would be 0. If string not found was reported as 0 you would not know if it was not found or found at the beginning. -1 is never a valid value for a position in a string.
As to your test
if( Array.indexOf(String) ) { ... }
you could instead use
if( 1+Array.indexOf(String) ) { ... }
to avoid using the !== -1 test.
As a general consideration, the result of Array.indesOf() is overloaded. The result contains both the funciton result and an error code. This overloading allows the function call to be used directly in a test. Consider, however, that if the function call is in the if statement you probably will need to call the function again, which is an efficiency loss. If before the if you made an assignment of the result and then tested the result you would be computationally more efficient. There is not even a memory cost because variables in funtions are on the stack which is cleared on function return if you keep the variable local.
A function that returned a structure containing a success/fail flag and a result is a clean way to do such a thing that generalizes function calls that may fail, and is a convenient place to put exception handling without complicating the simple test you want to do.
Because in almost every programming language, 0 is the first position of an array.
indexOf() gives you the position of the element in the array and valid index of array starts from 0, 1, ... and so on till the array.length-1 so if the indexOf() would return 0 for non existence element then that would be incorrect as 0 is a valid index. Thus -1 is used.
Let's say I have the following code:
var t = $("#objectID").html();
Checking that t is defined and has a proper value is easy.
if (typeof(t) === 'undefined' || t == null || t == '')
t = 'something else';
OR
var t = $("#objectID").html() || 'something else';
My question is though, what if you have something like the following: How would would you check it for undefined values before continuing?
$("#object").find("element").html().replace(/ |t/g, '').trim();
How do I ensure that each part of the object is legitimate before continuing down the line without having a large block of checks?
What if there's many things similar to .replace and .trim, like 10 or so? How do you check for each one?
You can use the function parameter of .html()
$("#object").find("element").html(function(html){
return ((html || 'Something').replace(/ |t/g, '') || 'Something else').trim();
});
So, what you are doing is first you're checking html has value and give it some default value if it doesn't have one. Then you group the returned string from replace and check if it has truthy value or give it a default value too and then trim it.
Here's how I would do that, checking as needed.
var element = $("#object").find("element");
var t = element.length ? element.html() : '';
t = t.replace(/ |t/g, '').trim();
First step is making a variable called element to save the jQuery object. Anytime you use the same jQuery search more than once, it's a good idea to save it to a variable: it avoids repetition and speeds up performance.
The next step is calling jQuery's length method to test if it really found any HTML elements. If either "#object" or "element" are not found, element becomes an empty jQuery object with a length of 0, and 0 is considered false in a JavaScript conditional check.
If the length of element is at least 1, then we know it's legitimate, and call safely html() on it.
If length is 0, then t is just set to an empty string. Checking length was necessary because calling html() on an empty jQuery object would have returned undefined instead of a string and caused an error.
I used the ? conditional operator for brevity but you can do the exact same check with an if statement
var element = $("#object").find("element");
if (element.length) {
var t = element.html();
} else {
var t = '';
}
t = t.replace(/ |t/g, '').trim();
I like making t default to an empty string, to ensure the variable is always a string. That way I can call replace() or trim() or any other string method with it.
An empty string also evaluates to false in JavaScript conditions, making it easy to check later on.
if (t) {
doSomethingWith(t);
}
Here is jquery code in rails app. The purpose of the code is to eval the value of #rfq_need_report and show the #rfq_report_language if need_report is true or hide if false:
$(document).ready(function() {
var rpt = $('#rfq_need_report').val();
alert(rpt);
if (rpt) {
alert(rpt);
$('#rfq_report_language').show();
alert('show');
} else {
$('#rfq_report_language').hide();
alert(rpt);
alert('hide');
}
}); // end ready
The alert here is just for debug. The rpt is false, however alert('show') gets executed. It seems that the if loop is taking false and decided to execute the loop for true. Sometime If loop is working and sometime it does not. What could cause this strange behavior? Thanks.
In HTML the value field of any input like value="something" is always evaluated as a string. My guess is that in javascript you either set that value to true or false but it is in fact set as "true" or "false" as strings. You could try what was answered on this topic : How can I convert a string to boolean in JavaScript?
rpt could be a string, therefore converting it into a boolean will help:
if(rpt === "false") { rpt = false; } else { rpt = true; }
I have to assume that $('#rfq_need_report').val() is not passing back an actual boolean value, but something that JavaScript considers 'truthy', which is why your if statement executes the truth clause.
There are two quick methods (that I use) to convert 'truthy' values to an actual boolean:
1: var bool = !!truthy;
2: var bool = truthy === 'true'
I use the second when expecting a string value, and the first when not expecting a string.
The first example may need an explanation, so...
The first ! "nots" the truthy value to an actual boolean, albeit the opposite of what I wanted, the second "nots" it right back to where it should be.
For more examples of truthy vs falsy, simply pop javascript truthy falsy into your favorite search engine and start reading. My personal quick reference is: Truthy and falsy in JavaScript