Why is else if block ignored when I add else block? - javascript

Why this happens? I'm doing exercise on FreeCodeCamp (Return the lowest index at which a value (second argument) should be inserted into an array (first argument) once it has been sorted. The returned value should be a number.)
I know there are better ways to do this but I'm interested in this problem.
This is my code:
function getIndexToIns(arr, num) {
let pos = 0;
arr.sort((a, b) => a - b);
console.log(arr);
for(let arrs in arr) {
if (num == arr[+arrs]) {
return pos = +arrs;
}
else if (num < arr[+arrs]) {
pos = ((+arrs));
return pos;
}
else {
return "why"
}
}
return 0;
}
console.log(getIndexToIns([2, 20, 10], 19));
console.log(getIndexToIns([2, 5, 10], 15));

The problem is you are returning "why" at the start of the loop, so basically 19 would be compared to 2, and when it finds that 19 === 2 is false and 19 < 2 is false, it returns "why" and gets out of the function without looping through the elements, same goes for the second array.
Try to use an array in which all the values are bigger than num and you will see that it gives you 0.
the solution would be to erase the third else altogether.
Hope this helped you.

The problem is in your if-else-if flow. The if-else-if work procedure is like below:
if is false, check next else if condition
if next else if condition is also false, will check the next else if condition if ther is any.
if there is no more else if condition, it will find else condition and work on that, if not found, will work on rest of statements
So, in your case, if first if is true, the look works only once, if that is false, then check next else if and if it is true, the loop ends, otherwise directly goes to else condition and returns from here running the loop only once. That's why it runs only once.

Related

Difficulty with Boolean and arrays in Javascript

Here, I am trying to write a code that takes a list of integers as a parameter and searches for the value 7. The function will return a boolean value representing true if 7 is in the list and false if it is not. This is what I have tried so far:
Could it be something with my else statement? Do I end it too soon? Or not soon enough?
You can simply use an array and use includes as per ECMA2016 like below:
if([2,5,7].includes(value)) {
return true;
}
return false;
or with list
var flag = false;
for(var i=0; i<arguments.length; i++)
{ if(arguments[i] == this) { flag = true; break; }}
return flag;
Javascript already has a function to do this. Array.prototype.includes(). You use it like this:
const containsSeven = list.includes(7)
If you are looking for something more complicated, like whether an item is an object and contains a particular key value pair for example, you can use Array.prototype.some()
Your declaration of the if statement is wrong. The else tag is on the wrong line. If you use else, it should come after the if-block.
But moving the else-block up, won't fix your function, because it will only return true if the first element in your array is a 7.
There are many good ways to do it, such as using higher order functions, but as it seems you are new to the language.
EDIT: Therefore, I would suggest one of the two simple ways below:
1) You could store the number of 7s found in the array in a for loop. Afterwards return false if the number of 7s is 0 or true if it the number is higher than 0
2) Another, much quicker way would be to return true in the for-loop when you encounter a 7 and after the for-loop just return false. Because a return statement exits the scope - which is your function - not only the for-loop would come to an end but also your function would return true much earlier.
For the second option, your function would look like this:
function find_value(list) {
for (let i = 0; i < list.length; i++) {
if(list[i] == 7) {
return true
}
}
return false
}
You can coerces to boolean the result of Array.prototype.find() which returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
Code:
const list1 = [4, 5, 6, 7, 8];
const list2 = [1, 2, 3, 4, 5];
const findTheNumber = (arr, num) => !!arr.find(n => n === num);
console.log(findTheNumber(list1, 7));
console.log(findTheNumber(list2, 7));
Try this way
function search(list , value){ // Value = 7;
return true ? list.indexOf(value) > -1 : false
}

Can forEach in JavaScript make a return? [duplicate]

This question already has answers here:
What does `return` keyword mean inside `forEach` function? [duplicate]
(2 answers)
Why does this forEach return undefined when using a return statement
(5 answers)
Closed 1 year ago.
I wonder if forEach in JavaScript can make a return, here is my code:
var a = [0, 1, 2, 3, 4];
function fn(array) {
array.forEach(function(item) {
if (item === 2) return false;
});
return true;
}
var ans = fn(a);
console.log(ans); // true
I want to find out if 2 is in my array, if so, return false, but it seems that the forEach function has looped the whole array and ignore return.
I wonder if I can get the answer I want with forEach ( I know I can get what I want using for(..))? dear friend, pls help me, with great thanks!
You can use indexOf instead https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
function fn(array) {
return (array.indexOf(2) === -1);
}
Also from the documentation for forEach - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Note: There is no way to stop or break a forEach() loop other than by
throwing an exception. If you need such behaviour, the .forEach()
method is the wrong tool, use a plain loop instead.
So, the return value cannot be used the way you are using it. However you could do a throw (which is not recommended unless you actually need an error to be raised there)
function fn(array) {
try {
array.forEach(function(item) {
if (item === 2) throw "2 found";
});
}
catch (e) {
return false;
}
return true;
}
In this case .indexOf() is probably what you want, but there's also .some() when a simple equality comparison is too simple:
var ans = a.some(function(value) { return value === 2; });
The .some() function returns true if the callback returns true for any element. (The function returns as soon as the callback does return true, so it doesn't bother looking beyond the first match.)
You can usually use the .reduce() function as a more general iteration mechanism. If you wanted to count how many instances of 2 were in your array for example:
var twos = a.reduce(function(c, v) { if (v === 2) c += 1; return c; }, 0);
Others have mentioned .indexOf() and .some(). I thought I would add that a good old fashioned for loop gives you the absolute most iteration control because you control the iteration and your processing code is not embedded in a callback function.
While .indexOf() already does exactly what you need, this code just shows how you can directly return when using the old fashioned for loop. It is somehow out of favor these days, but is often still the best choice for better looping control.
function fn(array) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] === 2) return false;
}
return true;
}
Using the for loop, you can iterate backwards (useful when removing items from the array during the iteration), you can insert items and correct the iteration index, you can immediately return, you can skip indexes, etc...
forEach returns undefined by specification. If you want to find out if a particular value is in an array, there is indexOf. For more complex problems, there is some, which allows a function to test the values and returns true the first time the function returns true, or false otherwise:
a.some(function(value){return value == 2})
Obviously a trivial case, but consider if you want to determine if the array contains any even numbers:
a.some(function(value){return !(value % 2)})
or as an ECMA2015 arrow function:
a.some(value => !(value % 2));
If you want to test if a particular value is repeated in an array, you can use lastIndexOf:
if (a.indexOf(value) != a.lastIndexOf(value) {
// value is repeated
}
or to test for any duplicates, again some or every will do the job:
var hasDupes = a.some(function(value, i, a) {
return a.lastIndexOf(value) != i;
});
An advantage of some and every is that they only process members of the array until the condition is met, then they exit whereas forEach will process all members regardless.
You said you want with forEach, so I modified your code:
function fn(array) {
var b = true;
array.forEach(function (item) {
if (item === 2) {
b = false;
}
});
return b;
}
var a = [0, 1, 2, 3, 4];
function fn(array, callback) {
var r = true;
array.forEach(function(item) {
if (item === 2) r = false;
});
callback(r);
}
fn(a, function(data) {
console.log(data) //prints false.
});
You can use callbacks as mentioned above to return the data you need. This is not same as the return statement but you will get the data.

Eloquent Javascript 2nd. Chapter 4. Computing Correlation. Lycanthrope’s log - [IndexOf Defined] Pt 1

I am currently going through Eloquent Javascript and came upon the were-squirrel example. There is a piece of code we are using to create a table/matrix for when Jacques(the subject of the problem) turns into a squirrel. It reference's a journal we made earlier.
here is the code.
function hasEvent(event, entry) {
return entry.events.indexOf(event) != -1;
}
function tableFor(event, journal) {
var table = [0, 0, 0, 0];
for (var i = 0; i < journal.length; i++) {
var entry = journal[i], index = 0;
if (hasEvent(event, entry)) index += 1;
if (entry.squirrel) index += 2;
table[index] += 1;
}
return table;
}
console.log(tableFor("pizza", JOURNAL));
// → [76, 9, 4, 1]
Now I understand what the function tableFor does and how it references the event from the variable journal (we have the journal as separate file and reference) but I don't understand the != 1 and returning inside the function tableFor. I assume we want to determine if this event we are looking for returned true if this is the case why are we not making an "if" entry? or perhaps == 0, or == 1? Am I missing something?
If someone could explain everything about
return entry.events.indexOf(event) != -1;
That would be greatly appreciated.
The indexOf function returns a positive number (or zero) if and only if there is an occurrence of whatever is passed in. If there is not an occurrence indexOf returns -1. The hasEvent function will return true if the event has occurred, otherwise it will return false.
What the OP asks has two sides:
How indexOf function works
Why does it not use if statement when it is comparing
First question was answered by the accepted answer. However, second one was not.
The OP seems to understand it as he accepted the answer but for the other viewers of this question, it may still be unclear.
function hasEvent(event, entry) {
return entry.events.indexOf(event) != -1;
}
is equivalent of below:
function hasEvent(event, entry) {
if (entry.events.indexOf(event) != -1)
return true;
else
return false;
}

Why is Javascript 'every' function returning false?

I have a quick question on why my function is returning false, when I expect it to be returning true. I have looked at the documentation for Array.prototype.every, and I still can't seem to find it. Thanks for your help in advance.
For some context, this is part of a coderbyte question called arithGeo. The current function I am working on here is supposed to return true if the difference between each element is the same. Here, I expect this to return true, since each element is 5 apart from the next.
Here is my function
var arr = [5, 10, 15];
function isArith(arr){
var diff = arr[1] - arr[0];
return arr.every(function(val, ind, col){
// if statement checks to make sure I stay in bounds.
if(col[ind + 1] !== undefined){
var next = col[ind + 1] - val;
console.log(diff === next );
// logging shows the following statement to be true, for every iteration
return diff === next;
}
});
}
var arith = isArith(arr);
console.log('arith: ', arith) // logs false
On the last iteration you'll return undefined, which will be interpreted as false. The code does that because if the if fails (which it does on the last element) there's no return statement. If you add return true to the end after the if it should work.
When you reach the last element, you test to see if there is a next element so you don't compare the last element with nothing. That's great. But in that case, you forget to return anything, and the default return is undefined, which is falsy. Just put in else return true.

Implementing `continue;` keywords in jQuery's `each();` method

Imagine that I want to loop over a list of jQuery objects, and for each of them execute some functions. However, if in some place, a criteria is not met, then I simply want to continue; to other objects. The simple pseudo-code might be something like:
$('#element').each(function(){
// some code here
if (!$(this).is('.included')) {
continue; // This keyword of course, doesn't work here
}
// more code here, which won't get executed for some elements
});
I wan to achieve the same effect as:
for (var i = 0; i < 10; i++) {
if (i % 2 == 0 ) {
continue;
}
console.log(i);
}
I know that I can return false; somewhere inside each(); method, to completely break the looping. But I don't want to break looping. I only want to skip some elements. I also know that I can use if-else blocks to skip elements, but is there a more neat way to do this?
simply use return; instead of continue; (not return false;).
When you use the .each jQuery function, you're passing a function to be executed for each value in the Array. The continue keyword is not implied in functions, but only in a direct loop. The reason jQuery breaks when you return a false value is because of this line in the jQuery libary:
if ( callback.apply( object[ name ], args ) === false ) {
break;
}
jQuery purposely exits the loop when the executed function returns false. It would be common sense to add this, right? Since it uses === you can return anything that isn't directly equal to false, including undefined, null, 0, true, or anything. As long as it doesn't equal false, the loop will continue.
$.each([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], function(i) {
if(i > 5) { return false; } // if(i > 5) { break; }
if(i < 2) { return null; } // if(i < 2) { continue; }
console.log(i);
});
Your console would look like this:
2
3
4
5
Notice it didn't log 0 and 1. i was less than 2, so it continued without logging. Notice it didn't log 6, 7, 8, and 9. This is because when i became more than 5, it returned false.
The jQuery.each docs says:
" Returning non-false is the same as a
continue statement in a for loop; it will skip immediately to the next
iteration. "
I usually do return 'continue'; which is both readable and more self-explanatory than simple return;, return true; or return 1;
I've also encountered return 'non-false'; which is quite funny in a geeky way.
I don't really see the need for the continue statement:
$('#element').each(function(){
// some code here
if( $(this).is('.included') ) {
// more code here, which won't get executed for some elements
}
});
This ought to do exactly the same, unless I'm missing something.

Categories

Resources