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

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.

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.');
}

Fetch specific data with JS fecth

Does someone know how to get specific data when working with JavaScript fetch?
I'm working with: https://apiv2.bitcoinaverage.com/constants/exchangerates/global
and not sure how to just pick 1 currency. I have a forEach loop that shows all, but unsure how to just pick one to show.
to show all I use:
${data.rates[rate].name}
${data.rates[rate].rate}<br>
When I try to just show one I tried with a few different, but I feel like this makes the most sense:
${data.rates[rate].name == dkk}
${data.rates[rate].rate}<br>
But it does nothing. Does someone know how to specify when you want to only show one set of data?
${data.rates[rate].name == dkk}
I'm assuming the ${} syntax here is javascript string interpolation. What you're saying here is "interpolate the value of the equality between .name and dkk". So this is probably displaying "true" or "false" for you, I'd assume.
What you want to do first is say
let displayName = '';
if (data.rates[rate].name === dkk) {
displayName = data.rates[rate].name;
}
And then interpolate ${displayName}.
If this isn't what you intend to do, we'd have to see more code.
let html = '';
for (let rateShort in data.rates) {
const rateObj = data.rates[rateShort];
html += `${rateObj.name} ${rateObj.rate}<br>`
}
Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Examples
fetch('https://apiv2.bitcoinaverage.com/constants/exchangerates/global')
.then(res => res.json())
.then(data => data.rates.AED)
.then(console.log)
since the fetch syntax returns a Promise, you can use .then to work with the data. in the code above I used .then to just return the AED(which is the rate of United Arab Emirates) object from the data recieved from the fetch. I hope it helps
OP here, figured it would be nice to comment how this was solved in case someone sees this in the future:
rates.forEach(currency=>{
if(data.rates[currency].name == 'Danish Krone'){ //if currency name == 'something'
output = output +
`
${data.rates[currency].name}
${data.rates[currency].rate}<br>
`
}
})
so basically you cant write ".name == dkk" to get the name of the currency. i actually had to write an if statement to check if the name == 'currency name'. also(for this api atleast) i couldt write the short version of the currency(dkk), i had to write the full name in the if statement. after that getting the name and rate of the currency was the same as when you loop through all.
hope this helps someone in the future if you end up here :)

for_each inside if_else in JS

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");
});

What to do if there is no data in localStorage?

I'm in a dilemma, I have a search engine which I keep the last results, everything perfect until there.
The problem is that I do not know what to do if I do not have items already saved, ie if it is the first time I search.
if(localStorage.getItem("searchResults") === null) {
// I do not know what to do here ...
}
else {
// Here the code is supposed to do what it has to do
}
Should not I do anything, should I save an empty string, or would I have to change the logic I'm working on?
What are your friends, what are you doing? Thank you
I would have a variable called "noResults", and set it to false, when search results are 0, or you can make it fetch results from server. It's all about context and logic
You could set it to N/A:
if(localStorage.getItem("searchResults") === null) {
localStorage.setItem("searchResults", "N/A");
}
else {
// Here the code is supposed to do what it has to do
}
Or use the following, and when you check if searchResults is null, last search result should be empty.
if(localStorage.getItem("searchResults") !== null) {
// Here the code is supposed to do what it has to do
}
Maybe you don't need an if statement. The if statement provides you with code blocks that can be executed for truthy or falsely expressions.
Instead, use a logical OR || to define a default value.
var results = localStorage.getItem('searchResults') || 'No results...';

Adding multiple parameters to an else if statement?

Let me explain in more detail, I'm making a little sketch for my maths teacher that will calculate the missing sides and angles of a triangle. I have if/else/else if statements but I want an else if statement that will output something like "Check spelling" if none of the other statements are true. Basically, I want something that would do something like this (keep in mind I don't know how to program this yet)
// More code above
else if (side != "hypotenuse and adjacent"; "hypotenuse and opposite"; "opposite and adjacent") {
confirm("Please check spelling.");
}
Can you see what I am trying to do? A previous variable is called side and it prompts the user to input which sides of the triangle they have, so the sketch can work out the angle. What if they have a spelling mistake and it doesn't match any of the parameters I set, how would I make it follow out this block of code if they don't match? I may have just over-complicated things here but if someone could tell me how to do this, it would be greatly appreciated
You can try indexOf:
possibilities = ["hypotenuse and adjacent", "hypotenuse and opposite", "opposite and adjacent"]
// so if side not in that array (the same as not in any of that values)
if (possibilities.indexOf(side) == -1) {}
Are you asking for a default statement if none of the others are matched? Wouldn't that just be an normal else statement?
else{//what you want here}
The simplest way I can think of is to use if, else if and else. By using the else at the end, you won't need to write a huge check for the last line since all the previous.
if (A) { A is true }
else if (B) { Not A, but B }
else if (C) { Not A or B, but C }
else { Not A, B or C }
An much nicer way to do this trick, is to use a switch/case, which is described here.
switch(n) {
case A:
A is true
break;
case B:
B is true
break;
default:
Not A or B
}
However, if you only want the last check for "spell checking", I'd say #zishe has a neat answer to that.
The most simple way to do this is to use jQuery function:
$.inArray(value, array)
which returns either positive index if the string can be found inside of array or -1 otherwise. So the solutions should be something like this:
var myArray = ["hypotenuse and adjacent", "hypotenuse and opposite", "opposite and adjacent"];
// more code above
else if($.inarray(side, myArray) == -1) {
confirm("Please check spelling.");
}

Categories