Javascript: For Loop, need help understanding this exercise with if/else - javascript

I have this exercise that already got the answer, but after hearing the explanations, still don't understand. This is the exercise:
"write a function isUniform() which takes an array as an argument and
returns true if all elements in the array are identical"
This is the solution
function isUniform(numArr) {
var first = numArr[0];
for (var i = 1; i < numArr.length; i++) {
if (numArr[i] !== first) {
return false;
}
}
return true;
}
I got it almost right, but i did a else statement with the "return true" and it didn't work. Why does it work with the "return true" outside of the for loop?
(edited) This is how i did the first time:
function isUniform(numArr) {
var first = numArr[0];
for (var i = 1; i < numArr.length; i++) {
if (numArr[i] !== first) {
return false;
}
else {
return true;
}
}
}

If you return true outside the loop, then it checks every element in the loop until one matches the if test or it gets to the end of the loop.
If you return true inside the loop then it will always hit a return statement for the first element and then stop the loop.

I got it almost right, but i did a else statement with the "return
true" and it didn't work
The solution below would return the wrong results in some cases because all it does is find the first element within the array that's equal to first variable and return true, even though it hasn't searched the entire array.
function isUniform(numArr) {
var first = numArr[0];
for (var i = 1; i < numArr.length; i++) {
if (numArr[i] !== first) {
return false;
}
else {
return true;
}
}
}
I have this exercise that already got the answer, but after hearing
the explanations, still don't understand.
let's assume this is your array:
[10,10,13,10,10]
let's assume this is the variable first:
first = 10;
The if statement below which is within the for loop basically says if the variable first ( 10 ) is not equal to the element at the current index i (nth number within the array) then return false. This makes sense because if at this moment the variable first is not the same with the element at the specified index for example index 2 (number 13) then there is no point to carry on. Hence, it will return false.
if (numArr[i] !== first) {
return false;
}
now let's assume the array is:
[10,10,10,10,10]
let's assume this is the variable first:
first = 10;
now the variable first will be compared against each elementwithin the array and it says "is 10 not equal to the current element". in this case that's false because 10 is equal to 10. This will propagate down the array and control will never pass inside the if block. Eventually, control passes down to the return true statement.
if (numArr[i] !== first) {
return false;
}

It works because is the final statement in your function. Basically your function will return true if the condition inside for loop will not be triggered

Let's say you've got a broken printer which once in a while messes the printout. Now you printed 20 copies and want to know if every paper is fine. So now you would have to iteratively compare every copy until you found one which is not matching (and know it's time to get a new printer?). Or you've gone the way through the hole stack and know every copy is fine (and you've wasted time for nothing).

Related

How do I make this continue iteration through the FOR loop. Stuck on index 5

I'm building Connect Four per my beginner's project for the course I'm taking. I can't get it to move on past index 5. It seems to still return true that index 5 is undefined, even though after I click it the first time, it has turned red. I thought it would, per following click, run the for loop, starting with 5 again, but that it would then return False, and go back to the next index, 4, checking that one, and so forth. I have looked up a lot and I am just stuck. I can't figure it out.
I know that the code is not complete for the long run of the game; I'm just trying to understand this step, however ugly the code might be, so that I can move on to another piece.
var gClass = $(".G")
function returnBackgroundColor(rowIndex,colIndex){
// console.log($(colIndex[rowIndex]).prop("background-color"));
// console.log(rowIndex);
return($(colIndex[rowIndex]).prop("background-color"));
}
function changeColor(row, someClass){
someClass.eq(row).css("background-color","red");
}
function checkColor(someClass){
someClass.click(function() {
for (var row = 5; row > -1; row--) {
if (returnBackgroundColor(row, someClass) === undefined){
console.log(row);
return changeColor(row, someClass);
}else {
console.log("False");
}
}
})
}
checkColor(gClass)
You can use increment instead of decrement. And it is better to use dynamic endpoint in the loop
That's because of return changeColor(row, someClass);, here you are returning from the function overall. and ending the for loop.
If you want to go to the next index just use continue, but this isn't necessary since your scope is already done
for(let i =0; i < 5; i++)
for (var row = 5; row > -1; row--) {
if (returnBackgroundColor(row, someClass) === undefined){
console.log(row);
changeColor(row, someClass);
} else {
console.log("False");
}
}
You are misusing .prop in your returnBackgroundColor function. $.prop returns html properties and will not work directly on styles. You may try something like this to compare against instead: $(colIndex[rowIndex]).css('background-color')

Where do I place my return true statement

This is a basic javascript question I just want to better understand. I'm trying to understand if it matters where I place my return true statement. Here's the example code:
function isValid(input) {
for (var i = 0; i < input.length - 2; i++) {
var charOne = input.charAt(i);
var charTwo = input.charAt(i + 1);
var charThree = input.charAt(i + 2);
if (charOne === charTwo && charOne === charThree) {
return false;
}
return true;
}
}
isValid("ABB");
This returns true, but also returns true if I place the return true statement here:
function isValid(input) {
for (var i = 0; i < input.length - 2; i++) {
var charOne = input.charAt(i);
var charTwo = input.charAt(i + 1);
var charThree = input.charAt(i + 2);
if (charOne === charTwo && charOne === charThree) {
return false;
}
}
return true; // Moved this return statement
}
isValid("ABB");
Is one way wrong and the other correct?
Your first version, you are returning true within the for loop. That means its only going to execute your loop once and then return. That's likely a bug.
Your second version is likely correct. The return true statement executes from the function after the for-loop completes all iterations from [i..length-2).
second one, since in the first one after each iteration , you check if characters are equal and it will return false or return true in the first iteration itself.In, second one you check for all combinations and if it's never false then it must be true.
When you return inside a for loop you finish the whole loop and carry on outside it.
So the answer is it depends, if you want to miss out an item and carry on looping after the return statement then doing a return isn't what you want.
The return you put outside of the loop allows the loop to complete before returning the result.
Note a useful keyword you can use inside a loop if you want to finish the iteration rather than breaking the whole loop is continue.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue
I don't think one is wrong necessarily. I actually prefer a slightly different approach.
For clarity I generally will do something like this. So it is clearly one or the other.
With a return it is obvious that calculations within the function stop at that point. I just like it to look obvious.
if(charOne === charTwo && charOne === charThree) {
return false;
} {
return true;
}

How do i push an array[i] to another array

Basically i have to create a quiz with 3category. each with 5questions.
I would have to push the selected category-questions into this new array from the array with all the questions. I am unable to do so.
pushSelectedQuestion() {
for (var i = 0; i < this.getNumberOfQuestion; i++) {
if (usercategory == questionPool[i].category) {
mcqSelected.push(questionPool[i])
return mcqSelected;
}
}
}
usercategory = input from user.
if user chooses category 1.
if (1 == questionPool[1].category) (if it matches the category) then it will be pushed.
This is the part which i cant do
Well, from the information you've provided, there's one main issue here - the return statement is definitely shortcutting the loop - so even if you have everything else right, you'll only ever get the first matching question. The rest will have been cut out by the return statement, which stops the function and returns the value.
pushSelectedQuestion() {
for (var i = 0; i < this.getNumberOfQuestion; i++) {
if (usercategory == questionPool[i].category) {
mcqSelected.push(questionPool[i])
// the below line is causing this loop to end after the first time through the list.
// Remove it and then put a console.log(mcqSelected);
// here instead to see the value during each iteration of the loop.
return mcqSelected;
}
}
}
There are a lot of ways to accomplish what you want to do here though. For example, you could just use the javascript Array.filter method like so
let selectedQuestions = questionPool.filter(question => question.category == userCategory)
Maybe I am not understanding your question correctly, but can't you use nested arrays. If the questions are categorized beforehand that is.

What is wrong with my function that accepts an array of 2 element and check if the first element has every letter in the second element?

The function is given an array of 2 elements, 2 string to be exact. If the first element has every single letter in the second element (just one time, no case, no order), then the function returns true, if not false.
hey and hello works. But for example, mutation(["zyxwvutsrqponmlkjihgfedcba", "qrstu"]) is not returning true, somehow. I suspect there is something wrong with my if statement nested inside my for loop. Am I returning false or true multiple times, or some other problem?
function mutation(arr) {
var one=arr[0];
var two=arr[1];
one.toLowerCase();
two.toLowerCase();
var array=two.split("");
for(var i=0;i<array.length;i++){
if(one.indexOf(array[i]) !== -1){
return false;
}else return true;
}
}
mutation(["hello", "hey"]);
EDIT:
New discovery! if I move else return true to right after the end bracket of the for loop, mutation("hello", "neo") would return false, as wanted. But if I did that, then, mutation("hello", "hey") wouldn't return true, whereas before the change, it would.
This:
for(var i=0;i<array.length;i++){
if(one.indexOf(array[i]) !== -1){
return false;
}else return true;
}
is essentially (close enough) the same as this:
if(one.indexOf(array[0]) !== -1){
return false;
}else return true;
That is, you're not actually looping over anything. Because, no matter what, your loop always returns on the first iteration.
Consider the logic of what your function should do. If I understand correctly, you want to return false if the loop ever encounters a letter that isn't found in one. And to return true if the loop never encounters such a match. In that case, the default condition after the loop would be to return true. Something like this:
for(var i=0;i<array.length;i++){
if(one.indexOf(array[i]) === -1){
return false;
}
}
return true;
Basically, if the loop never found a "non-match", then it never returned false. So return true.
Edit: I also changed the comparison in the if, because I think you had it reversed. But I guess I'm not 100% sure on that, since the intent of the method is a little unclear. (The logic therein is a bit confusing, and the name of the method certainly doesn't help.) But hopefully you at least get the idea and can test/validate accordingly for your needs.
First, you should only return false if you find any character in one that wasn't in two, but you can only return true at the end of the loop, because then you know all characters match. It can't be in the else block.
Second, Shouldn't it be the other way around based on your description? You should iterate the characters of one and see if they are in two instead. Then it would fit.
function mutation(arr) {
var one=arr[0].toLowerCase();
var two=arr[1].toLowerCase();
var oneArr=one.split("");
var twoArr=two.split("");
console.log("Do all of '" + one + "' characters occur in '" + two + "'?");
for(var i=0;i<oneArr.length;i++){
console.log("Looking for " + oneArr[i]);
// If any characters in two didn't occur in one, it fails
var twoIndex = twoArr.indexOf(oneArr[i]);
if(twoIndex === -1) {
console.log("Can't find " + oneArr[i]);
return false;
} else {
console.log("Found at index " + twoIndex + " in '" + two + "'");
}
}
return true;
}
console.log(mutation(["hey", "hello"]));
console.log(mutation(["qrstu", "zyxwvutsrqponmlkjihgfedcba"]));
The main issue is that you're using an else block to return true inside the loop, so your loop is only checking one element then either returning true or false based on whether or not that element is in the first string. Put the return true statement after the for loop.
The second issue is that when you're checking for existence, you're returning false if it does exist. Use one.indexOf(array[i]) === -1 instead.
The final issue is that you're splitting a string to iterate it, but strings don't need to be split to be iterated using a for loop.
The rest of the changes just use less lines of code to do the same thing.
function mutation(arr) {
arr = arr.map(e => e.toLowerCase());
for(let i = arr[1].length - 1; i > -1; --i)
if(arr[0].indexOf(arr[1][i]) === -1) return false;
return true;
}
console.log(mutation(["hello", "hey"]));
console.log(mutation(["hello", "hel"]));
console.log(mutation(["zyxwvutsrqponmlkjihgfedcba", "qrstu"]));

What does a function with multiple return statements return?

This is from an exercise out of Head First JavaScript Programming book.
function findCarInLot(car) {
for (var i = 0; i < lot.length; i++) {
if (car === lot[i]) {
return i;
}
}
return -1;
}
var lot = [chevy, taxi, fiat1, fiat2];
I'm not going to write all the code basically the chevy, taxi, etc, are objects and the function is assigned one of the four objects and that value is give to a variable in this exercise. My question is what is going on with:
return -1;
So doesn't that get returned when the function completes? Or is it negated when
return i;
happens? Or are both values returned? Could someone sort this out for my poor brain and tell me what the rules are here.
Depending on which return it hits, that will be the only thing it returns
function findCarInLot(car) {
for (var i = 0; i < lot.length; i++) {
if (car === lot[i]) {
return i; // If this if statement is true I will return here and this function will end and I will never make it to the next return
}
}
return -1; // This will only get called if the above if statement is false
}
var lot = [chevy, taxi, fiat1, fiat2];
To me this function looks like, if you called it, it will loop through the car array, and if it finds said car in the array, it will return the index for that car.
If no car is found in the array, it will return -1 meaning the car doesn't have an index thus it is not in the array.
So, if we have
var lot = [chevy, taxi, fiat1, fiat2];
and we run
console.log(findCarInLot("fiat1")); // This will return 2 (Third element of the array)
This is returned from the return i inside the if statement and you will never see return -1
But if we do
console.log(findCarInLot("lamadamadingdong")); // This will return -1 as it was never found in the array of cars
Hope this helps.

Categories