for_each inside if_else in JS - javascript

I am new to the coding world, just started learning javascript. Im trying to design a table kind of output but unable to complete it. here is what I am trying to achieve
"Jan - 1 - quarter1" and on second row
"Feb - 2 - quarter1" ...etcetera
I made use of foreach , if/else and combine them both but couldn't get output maybe because we cannot add a foreach inside an if statement or so! can someone help where I am going wrong here?
const Months = ['jan','Feb']
if (Months = 'Jan'||'Apr'||'Jul'||'Sep') {
Months.forEach(function(Month, index) {
console.log(`${Month}--${index + 1}`)}
} else {
console.log(`${Month}--${index + 1}`)
}

It's pretty unclear what you're trying to accomplish but I wanted to offer a few things that I saw in your code. Since you are quite new, I understand you may not be super familiar with the language yet.
First, if (Months = 'Jan'||'Apr'||'Jul'||'Sep') will always return true no matter what, because you're making three separate mistakes! No worries, let me break them down for you.
The first mistake is that you are using a single equals sign in Months = 'Jan'. The single equals sign is what is known as an ASSIGNMENT operator. You are setting your variable Months equal to the string 'Jan'. What you are looking for is the STRICT EQUALITY operator === which tests to see whether two things are equal.
Please see this for reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
Your second mistake is that you are looking at the entire Months variable and trying to compare its values against strings. If you had used strict equality like so:
if (Months === 'Jan')
it still would have failed because Months is an Array. What you need to do is use Months.forEach to iterate over each element of the array, and then do an equality comparison over each month.
Your third mistake is the way you are using the OR operator ||.
Let's look at this code that will have fixed the prior two errors:
var months = ['Jan','Feb','Apr','Jul','Sep'];
months.forEach(element => {
if (element === 'Jan' || 'Feb' || 'Mar'){
console.log('Gotcha');
}
});
This will still always return true because EACH THING SEPARATE BY THE OR OPERATOR WILL BE EVALUATED INDEPENDENTLY. In order to properly run your test, you need a separate equality test in each section separated by an OR.
Run the following code snippet and look at the output:
var foo = "Hi";
const test1 = (foo === "Boo" || "You");
const test2 = (foo === "Boo" || foo === "You");
console.log(test1);
console.log(test2);
if (test1) {
console.log("This is true??")
}
So, what is going on there?
test1 winds up being assigned the value of "You" because the first part evaluates to false, so it assigns the second part.
test2 is false as we would expect.
But what happens if we use an "if" statement on test1, which is currently set to the string "You"?
Take a look at this answer for clarity. why does if("string") evaluate "string" as true but if ("string"==true) does not?
At the end of it all, what you want is something like this:
var months = ['Jan','Feb','Apr','Jul','Sep'];
months.forEach(element => {
if (element === 'Jan' || element === 'Feb') {
console.log('woot');
}
});

You want this? Make an array with the data that you want.. and go through the array with a foreach ?
var months = ['Jan','Feb','Apr','Jul','Sep'];
months.forEach(element => {
console.log(element + " - " + "quarter1");
});

Related

Troubles with the OR logical processor when coding discord bot

This is my current code, I'm wondering whether i have to use a mess of 'else if,' or if i can keep it compact.
if (message.content.toLowerCase().includes(`word`||`word2`||`word3`||`word4`||`wd`||`wd2`||`wd3`||`wd4`)){
message.reply('don\'t swear in front of me!');
message.delete({ timeout: 100 })
}})
The issue is that only the very first string, word, is being tested for.
All the other strings give no response when i type them into discord.
You have the right idea but you're using the || operator wrong. The || operator checks whether the statement on the left is false/null/undefined and if so, checks the statement on the right. The way you've defined it ('word'||'word2'||...), the operator takes the left statement, in this case the string 'word', and checks if it's false/null/undefined which it isn't because it's a string. Therefore it never checks any other words.
How I think you meant to use it, is like the following:
if (message.content.toLowerCase().includes(`word`) ||
message.content.toLowerCase().includes(`word2`) ||
message.content.toLowerCase().includes(`word3`) ||
...etc
){
// Code here
}
In theory this would work, but as you can see yourself this is far from clean and will get big and bulky with little effort. A better approach would be with using the Array.some() function which calls a function for each item in an array and returns true when one item passes the function. Take a look at the example below:
// Define an array of all the words that need to be checked.
const arrayOfBadWords = ['word', 'word2', 'word3', ...];
if (arrayOfBadWords.some(word => message.content.toLowerCase().includes(word))) {
message.reply('The message contains a blacklisted word.');
} else {
message.reply('The message looks absolutely fine.');
}

JavaScript studies. How Map() code are being executed?

Good evening.
I'm really struggling to get my head around this and I'm not sure if I'm missing something really stupid, but here is my code and my question.
const question = new Map();
question.set('question', 'What is the official name of the latest major JavaScript version?');
question.set(1, 'ES5');
question.set(2, 'ES6');
question.set(3, 'ES2015');
question.set(4, 'ES7');
question.set('correct', 3);
question.set(true, 'Correct answer :D');
question.set(false, 'Wrong, please try again!');
for (let [key, value] of question.entries()) {
if (typeof(key) === 'number') {
console.log(`Answer ${key}: ${value}`);
}
}
const ans = parseInt(prompt('Write the correct answer'));
console.log(question.get(ans === question.get('correct')));
Can someone please explain to me how, when I insert the right value into the prompt box; the interpreter?... knows to check the next line of code to display "Correct" or "Wrong in the console? depending on my input. I know we have a key of correct and its value is set to 3 but when do we tell it to execute the next lines of code depending on my answer? Does it just parse through the whole code, see a true statement and then executes whatever it is attached too, else execute the false statement? How, why? Apologies if I'm not coming through very clearly.
Your Map has an entry for key true and one for false. One of them is retrieved by using a key that corresponds to this expression:
ans === question.get('correct')
This expression returns true when the given answer is equal to the correct one, and false otherwise. This boolean result is then used as key for the next lookup in your set:
question.get(ans === question.get('correct'))
This effectively retrieves the value for either false or true -- as stored in your Map. And so the correct phrase is retrieved (and displayed).
If you would write that magic line a bit more verbose, it could look like this:
let output;
if (ans === question.get('correct')) { // get() returns 3 here.
output = question.get(true); // This retrieves 'Correct answer :D'
} else {
output = question.get(false); // This retrieves 'Wrong, please try again!'
}
console.log(output);
But realise how ans === question.get('correct') is a boolean expression, meaning it represents false or true, exactly what you want to pass as value to question.get in order to retrieve the phrase to be output.
So, instead of the if construct you can do:
let isCorrect = (ans === question.get('correct')); // false or true
let output = question.get(isCorrect); // This retrieves one of the two phrases
console.log(output);
And what those three lines do can be shortened into just one line:
console.log(question.get(ans === question.get('correct')));
NB: using Maps in this way doesn't look right. You should really use an array for the questions, and plain object(s) for the other stuff.

If/then calculation within Zap running even when statement is false

Essentially what I'm attempting to do is circumvent when users enter a number in a non-standard format. For example:
1.5 million should be 1500000
Previous Zap step extracts the number using the Formatter > Extract Number function. So the result is the variable rawNum and the original number is noformatNum.
var str = inputData.noformatNum;
var n = inputData.noformatNum.includes ("million");
if (n = true) return {
finalNum: Number(inputData.rawNum) * 1000000
};
else return { finalNum : inputData.noformatNum };
It works in that it completes the operation and turns 1.5 to 1500000, but it executes each time, even if noformatNum doesn't include "million" in the string. I'm not super experienced with Javascript, but after digging around W3C and the Zapier documentation for a couple hours I'm stumped. Any help is much appreciated. Thanks!
It looks like there's a small but significant syntax issue here. You'll want to use a triple equal sign === instead of a single = in your conditional.
if (n = true) return {
should be
if (n === true) return {
In an if...else statement, the part in parenthesis (the "condition") should be something that evaluates to either a "truthy" or "falsy" value. (MDN)
n = true assigns the value of true to the variable n, so JavaScript considers the whole thing "truthy" no matter what.
n === true compares n to true, which is what you want for the if...else statement to work. The value will be "truthy" or "falsy" depending on the value of n.

Finding neighbors in a game of five-in-a-row

I can declare a winner if a player gets five of their tokens in a row, and now I am trying to implement the feature of capturing an opponent's pieces. For example, I am player X, I can trap O's pieces like this X00X in any direction on the board. In order to implement this, is the following logic correct:
Find all neighbors around O, check and see if the neighbor is an X or an O, if there are two 0's in a row surrounded by an X on each side, I can take those pieces. Is there a better way to approach this problem? I am thinking of something like this:
function isOCaptured(token, row, col){
if(gameBoard[row][col]==="O" && gameBoard[row][col+1] === "X"
&& gameBoard[row][col-1] === "X"){
return true;
}
return false;
}
But it does not seems to return true when I place one O in between two X's.
Here is what my server.js and app.js look like right now: https://jsfiddle.net/Amidi/s3gnx3rL/4/ The HTML is just a 13 x 13 grid of buttons with an event attached to each which sends the buttons coordinates to the add() function in my app.js
Now, the problem seems to be that the code only works if the "O" was placed last. This can be solved with a for-loop.
for(var i = -1; i <= 1; i++) {
if (gameBoard[row][col+i]==="O" && gameBoard[row][col+i+1] === "X"
&& gameBoard[row][col+i-1] === "X") {
return true;
}
}
return false;
You can also use a slice:
// The closest 5 cells to the left/right of the newly added piece, as a string
var str = gameBoard[row].slice(col-2,col+3).join("");
// Look for the pattern "XOX" in those 5 cells. Double negation to return bool.
return !!str.match("XOX");
Old answer
According to your comment, the code was called like this:
if(isOCaptured(x,y)===true){console.log("y is between 2 x\s");
This means that the function is called with two instead of three arguments. That will result in the following values of the arguments: token = x, row = y and col = undefined.
The expression being evaluated will thus be:
gameBoard[y][undefined]==="O" && gameBoard[y][undefined+1] === "X"
&& gameBoard[y][undefined-1] === "X"
Which would evaluate as follows:
Evaluating gameBoard[y] will succeed, resulting in a column (the wrong one though).
Then we try indexing the column with undefined, and since the array doesn't contain an element called undefined, it will fail, resulting in (again) undefined.
Then we compare this value undefined with "0", which is obviously false.
The expression false && ... will return false, as will the whole function.
If the second part would have been executed, it would calculate undefined+1, which is (quite accurately) evaluated to NaN (not a number). The array doesn't contain NaN either, so this calculation would evaluated to false as well.
Now, for some advice:
The statement if(expr){return true} else {return false} can be simplified to just return expr.
These kinds of bugs are pretty easy to find if you use the Chrome Debugger (or Firebug for firefox), where you can step through the code and see exactly what happens and where stuff goes wrong.

cannot read shorthand javascript/query

i've spent ages trying to understand bootstrap's navigation bar, mainly by spending 4-5 days reading stackoverflow posts
& finally i think i've found an answer that helps!!!
trouble is, i can't understand the accompanying javascript/jquery code. i'm guessing its a shorthand version of js or something but just what it means i cannot decipher
basically, its the javascript code that appears on this jsfiddle page
$('.navbar').on('show', function () {
var actives = $(this).find('.collapse.in'),
hasData;
if (actives && actives.length) {
hasData = actives.data('collapse')
if (hasData && hasData.transitioning) return
actives.collapse('hide')
hasData || actives.data('collapse', null)
}
});
so, if anyone can explain to me what the code is doing on a line by line basis it'd be really cool
the first line i understand. its the weird-ass syntax in the next 6 lines that have me mystified
var actives = $(this).find('.collapse.in'),
hasData;
This creates two variables. One with elements picked from current scope that match the selector .collapse.in, and one empty variable.
if (actives && actives.length)
If actives exists and contains more than zero elements, do the following...
hasData = actives.data('collapse')
Retrieve arbitrary data stored under the key collapse. See https://api.jquery.com/jquery.data/ for more info.
if (hasData && hasData.transitioning) return
If hasData exists and hasData.transitioning is truthy, stop function execution.
actives.collapse('hide')
Call the collapse function on actives. This is not a native jQuery function, so you'll have to look up whatever plugin it comes from to make sense of the argument being passed in.
hasData || actives.data('collapse', null)
If hasData is truthy, skip this line. Otherwise, set the arbitrary data in actives variable to null.

Categories