OR Logic in if statement issue. - javascript

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.

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

if statment always executing

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

How to count how many consonants are in a string?

Am I somewhere near the solution? I always get a double number of the consonants.
I was convinced that this was the correct approach.
function consonants(str) {
var countConsonants = 0;
for (var i = 0; i <= str.length; i++) {
if (str[i] !== "a" || str[i] !== "e" || str[i] !== "i" ||
str[i] !== "o" || str[i] !== "u" || str[i] !== " ") {
countConsonants += 1;
}
}
return (countConsonants);
}
consonants("asdfghaaa");
I am expecting an answer of 5 i.e. sdfgh are the consonants.
Your logic is flawed, The operator in your condition should be AND && not OR ||, since you want to compare all the chars not just one of them :
function consonants(str) {
var countConsonants = 0;
for (var i = 0; i < str.length; i++) {
if (str[i] !== "a" && str[i] !== "e" && str[i] !== "i" &&
str[i] !== "o" && str[i] !== "u" && str[i] !== " ") {
countConsonants++;
}
}
return (countConsonants);
}
console.log(consonants("asdfghaaa"));
NOTE : The loop should stop at length-1 since arrays are 0 based, so replace :
for (var i = 0; i <= str.length; i++) {
__________________^^
By :
for (var i = 0; i < str.length; i++) {
__________________^
Hope this helps.
You can do
let str = 'asdfghaaa';
let result = str.split('').filter(e => e.match(/[^aeiou]/) != null).length;
console.log(result);
The main problem in counts lies within your conditions.
You're increasing the number of consonants whenever one of the conditions fail (that's what || does, known as the OR operator). So whenever a character !== "a" OR !== "e", you're increasing the count, which is wrong. (Imagine that a is !== 'e', so you're counting a as a consonant).
Change the || binary operator to && (AND); this way, you're only increasing the consonant count whenever the current character str[i] is not among the values you're verifying for (a, e, i, o, u, ' ').
As others pointed out, you're also likely to run into an error as the max value of i should be Length-1.
There also other problems you need to consider:
What happens when the character is an uppercase letter?
What happens when the character is a punctuation mark or a number?
For a beginner, this may not be relevant, but it's well worth getting these techniques under your skin: It's more readable to create an array that contains all of the value you're verifying for ["a","e", etc] and then, for each char in the source string, just verify if array.indexOf(str[i]) >= 0 (which means that the character is included in the array).
Your answer is almost right. The only problem is || instead of &&. You're checking that it's not a AND it's not e AND it's not i, etc. Your function comes out true for every letter, since a is (not a || not e), right?
function consonants (str) {
return str.match(/[aeoiu]/gi)||[].length;
}
May be not good for long string.
You need to and your conditions because if you use || the condition always evaluates to true. Your loop should go from 0 to index < str.length.
function consonants(str) {
var countConsonants = 0;
for (var i = 0; i < str.length; i++) {
if (str.charAt(i) !== "a" && str.charAt(i) !== "e" && str.charAt(i) !== "i"
&& str.charAt(i) !== "o" && str.charAt(i) !== "u" && str.charAt(i) !== " ") {
countConsonants++;
}
}
return countConsonants;
}
console.log(consonants("asdfghaaa"));
I had this challenge too here is how i did:
const paragraph = "A quick brow fox is trying to bite me."
paragraph.match(/(?![aeiou])[a-z]/gi, "").length
Source: https://forum.freecodecamp.org/t/regex-for-consonants/282833/4
Here is a working example
let str="Hello world.";
let vowel=str.match(/[aeiou]/gi).length;
let consonant = str.match(/[^aeiou .]/gi).length;
console.log("Vowel "+vowel+"\n");
console.log("Vowel "+consonant+"\n");

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

Javascript Function that returns true if a letter?

So I'm looking to write a function for my class that is titled isAlpha that accepts a character (preferably a string with length of 1) and returns true if it's a letter and false if it's not.
The thing is I'm completely stuck on where to go. This is the example the instructor gave in class:
var isAlpha = function(ch){
//if ch is greater than or equal to "a" AND
// ch is less than or equal to "z" then it is alphabetic
}
var ltr ="a", digit =7;
alert(isAlpha(ltr));
alert(isAlpha(digit))
I'm not sure what to do with that though, I've tried a few different things like:
var isAlpha = function(ch){
if (ch >= "A" && ch <= "z"){
return true
}
}
alert(isAlpha(ch))
Can anyone point me in the right direction of how to this function started?
You could just use a case-insensitive regular expression:
var isAlpha = function(ch){
return /^[A-Z]$/i.test(ch);
}
If you are supposed to be following the instructions in the comments about greater than and less than comparisons, and you want to check that the input is a string of length 1, then:
var isAlpha = function(ch){
return typeof ch === "string" && ch.length === 1
&& (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z");
}
console.log(isAlpha("A")); // true
console.log(isAlpha("a")); // true
console.log(isAlpha("[")); // false
console.log(isAlpha("1")); // false
console.log(isAlpha("ABC")); // false because it is more than one character
You'll notice I didn't use an if statement. That's because the expression ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" evaluates to be either true or false, so you can simply return that value directly.
What you had tried with if (ch >= "A" && ch <= "z") doesn't work because the range of characters in between an uppercase "A" and a lowercase "z" includes not only letters but some other characters that are between "Z" and "a".
First make sure it is a string, then use regex.
var isAlpha = function(ch){
return typeof ch === "string" && ch.length === 1 && /[A-Za-z]/.test(ch);
}
if it's only one character you need:
var isAlpha = function(ch){
return /^[A-Za-z]{1,1}$/.test(ch)
}
notice that the {1,1} here means the character appears at least once and at most once. If you only test one character you can just remove this {1,1}, if you want to test more than one character, you can update this into {n,m} according to your requirement.
The regex is your friend.
var isAlpha = function(ch){
return ch.match(/[0-9]/) != null
}

Categories

Resources