if statment always executing - javascript

I am trying to solve this simple algorithm that change a string depending on the first character, it always run on (If) even if it doesn't meet it requirement; i can just check the "freecodecamp" for answer but i want some one to explain to me why it never get to the else statement thanks
let translatePigLatin = str => {
let myArr = str.split("")
let arr = [...myArr]
if(arr[0] === "a" || "e" || "u" || "i" || "o"){
return [...arr,"w","a","y"].join("")
}else{
let firstChar = arr.shift()
arr.push(firstChar)
console.log(arr)
return [...arr,"a","y"].join("")
}
}
console.log(translatePigLatin("algorithm"));

if(arr[0] === "a" || "e" || "u" || "i" || "o")
This is always true because it is comparing arr[0] to "a", then checking the truth value of string "e" etc. Those following values are always true. You need something like:
if(arr[0] === "a" || arr[0] === "e" || arr[0] === "u" || arr[0] === "i" || arr[0] === "o")
or
if("aeiou".includes(arr[0]))

You just need rewrite your condition to the next:
if(arr[0] === "a" || arr[0] === "e" || arr[0] === "u" || arr[0] === "i" || arr[0] === "o")
you can extract condition to the method, it will be more readable

Related

Function that Returns the Length of an Array of Specific Characters (Javascript) [duplicate]

This question already has answers here:
Check variable equality against a list of values
(16 answers)
Closed 1 year ago.
I need help writing a function that returns the length of an array of characters that match "a" || "e" || "i" || "o" || "u".
function getCount(str) {
let count = str.split("").filter((ch) => {
return ch === "a" || "e" || "i" || "o" || "u"
}).length;
return count;
}
console.log(getCount("abracadabra"));
//"a" || "e" || "i" || "o" || "u"
For some reason, it is returning 11, instead of the correct value of 5.
Any help would be appreciated!
Sorry but you're not doing the comparison right.
function getCount(str) {
let count = str.split("").filter((ch) => {
return ch === "a" || ch === "e" || ch === "i" || ch === "o" || ch === "u"
}).length;
return count;
}
console.log(getCount("abracadabra"));

Can someone explain to me how the scope of the logical "OR" operator works in Javascript?

here's my code.
function getVowelCount(str) {
let array = str.split("");
let vowelCount = array.reduce((acc, curr) => {
if (curr === 'a' || curr === 'e' || curr === 'i' || curr === 'o' || curr === 'u') {
acc++
} return acc
}, 0);
return vowelCount
}
I'm new to coding and I've started with Javascript. Could someone be so kind as to explain why I can't use "(curr === 'a' ||'e' || 'i' || 'o' || 'u')" in my if statement. I thought that would have been processed as; "If the current value is 'a' OR 'e' OR 'i' etc...
Thanks.
=== has higher order of operations than ||.
Operators of equal order are evaluated left to right.
(see mdn for full order).
So curr === 'a' ||'e' || 'i' || 'o' || 'u' is equivalent to
(((((curr === 'a') ||'e') || 'i') || 'o') || 'u')
Which can be reduced to curr === 'a' ? true : 'e'.
Just like there's an order of operations for math (multiplication/division before addition/subtraction), javascript's operators have an order. In (curr === 'a' ||'e' || 'i' || 'o' || 'u'), the highest priority is the ===, so it starts by comparing curr === 'a'. This is going to result in either true or false. Let's assume false.
Next up there's all the ||'s. These are done left to right, so it compares false || 'e'. Every string except for an empty string is "truthy", so false || 'e' is truthy as well.
It would continue moving to the right, except logical OR operators will short circuit once the outcome is guaranteed. So the whole expression is truthy.
Even if || had a higher precedence, it wouldn't make this work. With 'a' || 'e', both of those are "truthy", so it just takes the first truthy value, which is a. And this would repeat, meaning 'a' || 'e' || 'i' || 'o' || 'u' is a complicated way of saying 'a'.
console.log('a' || 'e' || 'i' || 'o' || 'u')

Why does charAt not detect a string?

Why does the following function return a vowel at index 2 when, index 2 is NOT a vowel?
function isVowel(name) {
console.log("The third letter of " + name + " " + "is " + name.charAt(2))
if (name.charAt(2) === "a" || "i" || "o" || "u")
console.log("3rd letter is vowel")
else
console.log("3rd letter is NOT vowel")
}
isVowel("abcdefg")
/*Outputs:*/ The third letter of abcdefg is c
3rd letter is vowel
In JavaScript (and all the other languages with similar syntax), this line:
if (name.charAt(2) === "a" || "i" || "o" || "u")
means
if name.charAt(2) === "a"
or "i"
or "o"
or "u"
it does not mean
if name.charAt(2) === "a"
or name.charAt(2) === "i"
or name.charAt(2) === "o"
or name.charAt(2) === "u"
In a lot of languages you'd get an error because "i" isn't a boolean value, so || "i" is an odd thing to say; but JavaScript is happy to do type coercion, and so false || "e" results in true because "e" is a "truthy"1 value.
To make it mean what you want it to mean, you have to repeat the left-hand operand:
if (name.charAt(2) === "a" ||
name.charAt(2) === "i" ||
name.charAt(2) === "o" ||
name.charAt(2) === "u")
You might want to use a variable to avoid repeatedly calling charAt, or look at doing something else, like this typical "is X in Y" approach:
if ("aiou".indexOf(name.charAt(2) !== -1)
Side note: Aren't you missing "e" (and sometimes "y")? ;-)
1 "truthy value" - Values that coerce to true when used as booleans are truthy; ones that coerce to false are "falsy." The falsy values are 0, "", NaN, null, undefined, and of course, false; all other values are truthy.
A non-empty string is treated as a truthy value in JS so the if statement would be always true. If the first condition name.charAt(2) === "a" fails it will check the second condition "i" which would be always treated as truthy since it's non-empty string.
Instead, you can do something simple like this using String#indexOf method.
if ("aiou".indexOf(name.charAt(2)) > 1)
Change the if condition to
name.charAt(2)==='a' || name.charAt(2)==='i' || name.charAt(2)==='o'||name.charAt(2)==='u'
The || operator does not work like that:
if (name.charAt(2) === "a" || "i" || "o" || "u")
is syntactically correct but it won't do what you expect. You need to do a separate comparison to each vowel. Alternatively, you can keep the vowels in a string and check by search or lookup:
if ("aeiou".indexOf(name.charAt(2)) >= 0)
or
if ("aeiou".includes(name.charAt(2)))
(The .includes() function used in the latter example doesn't have widespread support yet.)
You need to check every letter with a single comparison.
function isVowel(name) {
console.log("The third letter of " + name + " " + "is " + name.charAt(2))
if (name.charAt(2) === "a" || name.charAt(2) === "i" || name.charAt(2) === "o" || name.charAt(2) === "u") {
console.log("3rd letter is vowel");
} else {
console.log("3rd letter is NOT vowel");
}
}
isVowel("abcdefg");
A shorter ocde could be to check a string with the vowels and get the position of the letter, to check against.
function isVowel(name) {
console.log("The third letter of " + name + " " + "is " + name.charAt(2))
if ('aeiou'.indexOf(name[2]) !== -1) {
console.log("3rd letter is vowel");
} else {
console.log("3rd letter is NOT vowel");
}
}
isVowel("abcdefg");
You can use an Object as a hash map to check in constant time if a character is a vowel (your vowel check condition was wrong, it is always returning true)
var vowels = {
a: true,
i: true,
e: true,
o: true,
u: true
}
if(name.charAt(2) in vowels) {
...
}
Why is your condition always returning true?
Because those are all equivalent in your case:
if (name.charAt(2) === "a" || "i" || "o" || "u")
if ((name.charAt(2) === "a") || ("i" || "o" || "u"))
if ((name.charAt(2) === "a") || true)
if (THIS_CAN_BE_ANYTHING || true)
if (true) // So, your condition is always true

Why is the 'o' is true? Javascript(Angular)

Help me please, I'm trying to make a rule for the little game and there is the problem.
I'm creating winning combination and say if the cell && cell+1 && cell+2 == to 'X' then you win, but when between two "X"s presents "o" it also says that "X" wins. Why? Please see my code and the game example on link a the bottom.
this.rezult = function(){
this.arr2.forEach(function(arr, i, innerArr){
arr.forEach(function(val, j){
var wincomb = innerArr[i][j] && innerArr[i][j+1] && innerArr[i][j+2];
var wincomb2 = innerArr[i][j] && innerArr[i+1][j] && innerArr[i+2][j];
var wincomb3 = innerArr[i][j] && innerArr[i+1][j+1] && innerArr[i+2][j+2];
console.log(wincomb == "X" && innerArr[i][j] !== "o");
// console.log(innerArr);
// THE RULE
if(wincomb == "X"){
alert(' X wins!');
}
});
});
};
Link to JSFiddle
In JavaScript, the && operator has interesting behavior with non-boolean values.
If the left-side of && is "truthy", the result is the right-side.
If the left-side of && is "falsey", the result is the left-side.
All non-empty strings are "truthy".
So, consider these examples:
("A" && "B" && "C") === "C"
("" && "B" && "C") === ""
(0 && "B" && "C") === 0
("X" && "X" && "O") === "O"
("O" && "O" && "X") === "X"
By the looks of it, you're trying to check if all 3 values are equal. You shouldn't use && for that, you should use === for that.
At the risk of doing your homework for you ;) here's a good way to do this:
function areTheSame(a,b,c) {
return a === b && b === c;
}
var down = areTheSame(innerArr[i][j], innerArr[i][j+1], innerArr[i][j+2]);
var across = areTheSame(innerArr[i][j], innerArr[i+1][j], innerArr[i+2][j]);
var diagonal = areTheSame(innerArr[i][j], innerArr[i+1][j+1], innerArr[i+2][j+2]);
if (down || across || diagonal) {
var winner = innerArr[i][j];
alert( winner + " wins!");
}

OR Logic in if statement issue.

I am having a problem with the logic in my if statement. I am trying to have it check to see if the strings character is equal to a, e, i, o, OR u. And then if so add the character to the phrase string. Else add "x" to the phrase string.
The if statement seems to disregard my OR logic and returns true regardless if it is a vowel of not.
function translate(string){
var phrase = "";
for(i=0; i<string.length; i++){
if (string.charAt(i) === "a" || "e" || "i" || "o" || "u"){
phrase += string.charAt(i);
}else{
console.log("x");
}
}
console.log(phrase);
}
translate("this is fun");
Any help would be greatly appreciated! Thank you.
if (string.charAt(i) === "a" || "e" || "i" || "o" || "u"){
This is incorrect. If the first condition fails (the character is not "a"), it will always be truthy because it will evaluate "e", which is truthy (JavaScript returns the last evaluated part of an expression in a condition).
You could use...
// Define them somewhere out of the loop.
var vowels = ["a", "e", "i", "o", "u"];
// Your new condition.
if (vowels.indexOf(string.charAt(i)) > -1) {
You could also rewrite the whole thing like...
var vowels = ["a", "e", "i", "o", "u"];
var phrase = string
.split("")
.filter(function(char) { return vowels.indexOf(char) > -1; })
.join("");
jsFiddle.
You need to check each condition separately. For example:
if (string.charAt(i) === "a" || string.charAt(i) === "e" || ...);
To cut down on code bloat you can set a variable:
var char = string.charAt(i);
if (char === "a" || char === "e" || ...);
Or you can use this indexOf trick:
if (["a", "e", "i", "o", "u"].indexOf(string.charAt(i)) > -1);
In you code you are comparing string.charAt(i) with "a" || "e" || "i" || "o" || "u" which evaluates to true.
What you men to do is :
string.charAt(i) === "a" || string.charAt(i) === "e"
|| string.charAt(i) === "i" || string.charAt(i) === "o" || string.charAt(i) === "u"
In english we say : if my string is equal to 'a' or 'e' or 'i' .. but in javascript (and most other languages) we say : if my string is equal to 'a' or my string is equal to 'b' ..
Do it like this. The .indexOf() on strings is more widely available than the .indexOf() on Arrays.
if ("aeiou".indexOf(string.charAt(i)) > -1) {
Alex's answer is pretty good, but rather than using indexOf and an array (noting that Array.prototype.indexOf is ES5 so not supported by older browsers), you can use an object instead:
var vowels = {a:'a', e:'e', i:'i', o:'o', u:'u'};
if (vowels.hasOwnProperty(string.charAt(i).toLowerCase())) {
phrase += string.charAt(i);
} else {
...
}
The above is also not case sensitive, so A, E, I, O and U will also be added to the string. If you want it to be case sensitive, remove the .toLowerCase() part.
Edit
Alex got me thinking, again. To return an array of just the vowels in order:
function getVowels(s) {
return s.match(/[aeiou]/g);
}
To return a string where all non-vowels (consonants) are replaced with an "x":
function replaceConsonants(s) {
return s.replace(/[^aeiou]/g,'x');
}
To return a string of just the vowels:
function replaceConsonants(s) {
return s.replace(/[^aeiou]/g,'');
}
or
function getVowels(s) {
return s.match(/[aeiou]/g).join('');
}
etc.

Categories

Resources