This question already has answers here:
if statement in javascript always true
(5 answers)
Closed 6 years ago.
The else-statement below never executes even if the if-statement is false. I think I've made some very basic mistake but can't figure out what.
var a = ["king","queen","100"];
for (var i=0; i<a.length; i++) {
if (a[i] === "king" || "queen"){
console.log("monarch");
}
else {
console.log("The number is: "+ parseInt(a[i]));
}
}
// This prints out "monarch" 3 times
Should be:
var a = ["king","queen","100"];
for (var i=0; i<a.length; i++) {
if (a[i] === "king" || a[i] === "queen"){
console.log("monarch");
}
else {
console.log("The number is: "+ parseInt(a[i]));
}
}
You wrote your boolean expression the way we would speak a spoken language, "A is either 1 or 2". That's not the way the OR is interpreted.
Either the left side of the OR is true: a[i] === "king" is true; or the right side of the OR is true: "queen". It's evaluating the string by itself, and the string "queen" is not null, so it evaluates to true.
You gotta make your two conditions separately with || as follow: a[i] === "king" || a[i] === "queen"
Related
This question already has answers here:
Check variable equality against a list of values
(16 answers)
What is the difference between the `=` and `==` operators and what is `===`? (Single, double, and triple equals)
(5 answers)
What is an off-by-one error and how do I fix it?
(6 answers)
Closed 4 months ago.
I'm having problem with the conditional always returning true. I'm not sure if it's the value it's seeing as truthy in general but it's messing with me.
Problem: Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contain any char.
Examples input/output:
XO("ooxx") => true
XO("xooxx") => false
XO("ooxXm") => true
XO("zpzpzpp") => true // when no 'x' and 'o' is present should return true
XO("zzoo") => false
function XO(str) {
let on = 0
let xn = 0
let result = ""
for (let i = 0; i <=str.length; i++) {
if (str[i] = "x" || "X"){
xn++
} if (str[i] = "o" || "O") {
on++
};
if (xn == on || xn && on == 0){
result = true
}else if (xn !== on) {
result = false
}
return result
}
}
Seems the conditional is always returning true. Not sure if it's because the types are true (which is why I kept it strict).
You have 3 mistakes in your XO function.
You have used assignment operator : = instead of equality
comparison operator : ==.
You are checking condition str[i] == "x" || "X". The correct way to write this is : str[i] == "x" || str[i] == "X".
You are checking xn==on inside the for loop. You should check that once your for loop is over.
Here is the correct code -
function XO(str) {
let on = 0
let xn = 0
for (let i = 0; i < str.length; i++) {
if (str[i] == "x" || str[i] == "X") {
xn++
continue;
}
if (str[i] == "o" || str[i] == "O") {
on++
continue;
};
}
return xn==on;
}
You just use toLowerCase() and at the end return if on===xn
function XO(str) {
let on = 0;
let xn = 0;
for (let i = 0; i < str.length; i++) {
if (str[i].toLowerCase() === "x") {
xn++;
}
if (str[i].toLowerCase() === "o") {
on++;
};
}
return xn === on
}
console.log(XO("ooxx"))
console.log(XO("xooxx"))
console.log(XO("ooxXm"))
console.log(XO("zpzpzpp"))
console.log(XO("zzoo"))
have been struggling for the last couple of days with the following problem from codewars:
Write a function that takes a string of braces, and determines if the order of the braces is valid. It should return true if the string is valid, and false if it's invalid.
All input strings will be nonempty, and will only consist of parentheses, brackets and curly braces: ()[]{} .
What is considered Valid?
A string of braces is considered valid if all braces are matched with the correct brace.
Examples
"(){}[]" => True
"([{}])" => True
"(}" => False
"[(])" => False
"[({})](]" => False
So I'm really stuck with the code for this one, and this is what I have up to this point:
function validBraces(braces){
let opening = [ '(', '[', '{']
let closing = [ ')', ']', '}']
let count = 0
const left = []
const right = []
// I generate left and right arrays, left w/the opening braces from the input, right w/ the closing
for (let i = 0; i < braces.length; i++) {
if (opening.includes(braces[i])) {
left.push(braces[i])
} else if (closing.includes(braces[i])) {
right.push(braces[i])
}
}
if (braces.length % 2 !== 0) {
return false
}
// I know there's no point in doing this but at one point I thought I was finishing the program and thought I would 'optimize it' to exit early, probably this is dumb haha.
if (left.length !== right.length) {
return false
}
// The juicy (not juicy) part where I check if the braces make sense
for (let i = 0; i < left.length; i++) {
// If the list are made up of braces like ()[]{} add one to counter
if (opening.indexOf(left[i]) === closing.indexOf(right[i])) {
count += 1
} else // If left and right are mirrored add one to the counter
if (opening.indexOf(left[i]) === closing.indexOf(right.reverse()[i])) {
count += 1
}
}
//If the counter makes sense return true
if (count === braces.length / 2) {
return true
} else { return false}
}
console.log(validBraces( "()" )) //true
console.log(validBraces("([])")) //true
console.log(validBraces( "[(])" )) //false
console.log(validBraces( "[(})" )) //false
console.log(validBraces( "[([[]])]" )) //true
Some comments: I know I'm still not checking for this example ([])() but I thought of breaking this up into two smaller checks in some way.
Thank you if you read up to this point. I would appreciate guidance in some way, though I don't want the problem solved for me. I'm probably overcomplicating this in some way since its a 6kyu problem, if so a tip on how to approach it more cleverly would be very much appreciated.
Thank you in advance! :pray: :pray:
Hell yeah!! I'm very happy to finally reach to the solution myself using some of the hints given to me here:
function validBraces(braces){
let opening = [ '(', '[', '{']
let closing = [ ')', ']', '}']
let arr = []
//console.log(closing.indexOf(braces[")"]) === opening.indexOf(arr[")"]))
for (let i = 0; i < braces.length; i++) {
if (opening.includes(braces[i])) {
arr.push(braces[i])
} else
if (closing.indexOf(braces[i]) === opening.indexOf(arr[arr.length - 1])) {
arr.pop()
} else return false
} return arr.length === 0;
}
I was clearly overthinking it in the first place haha. Thanks for everyone that helped!
As Dave suggested, using a stack, I've wrote the code for it:
var leftBraces="([{";
var rightBraces=")]}";
function checkBraces(braces) {
var ok=true;
var stack=[];
for(var i=0; i<braces.length && ok; i++) {
var brace=braces[i];
if(leftBraces.includes(brace)) stack.push(brace);
else {
var leftBrace=stack.pop();
if(leftBrace==undefined) ok=false;
else if(leftBraces.indexOf(leftBrace)!=rightBraces.indexOf(brace)) ok=false;
}
}
if(stack.length) ok=false;
return ok;
}
Code assumes only braces (no spaces or other characters).
I'm using string.indexOf() that matches for leftBraces and rightBraces.
Also, within the for loop, notice the termination part (2nd): i<braces.length && ok - doesn't "have to" use the iterator and, if I'm not mistaken, can even be empty...
var validBraces = (s) => {
let objO = {'(': 0, '[': 1, '{': 2};
let objC = {')': 0, ']': 1, '}': 2};
let stack = [];
for (let i=0; i<s.length; i++) {
if (objO.hasOwnProperty(s[i])) {
if (stack.length === 0 || stack[stack.length-1].idx!==objO[s[i]])
stack.push({idx: objO[s[i]], count: 1});
else
stack[stack.length-1].count++;
}
else if (objC.hasOwnProperty(s[i])) {
if (stack.length === 0 || stack[stack.length-1].idx!==objC[s[i]])
return false;
else {
stack[stack.length-1].count--;
if (stack[stack.length-1].count===0)
stack.pop();
}
}
}
return stack.length === 0;
};
console.log(validBraces("(){}[]"));
console.log(validBraces("([{}])"));
console.log(validBraces("(})"));
console.log(validBraces("[(])"));
console.log(validBraces("[({})](]"));
Here is a simplified solution:
let isMatchingBraces = function(str) {
let stack = [];
let symbol = {
'(': ')',
'[': ']',
'{': '}'
};
for (let i = 0; i < str.length; i += 1) {
// If character is an opening brace add it to a stack
if (str[i] === '(' || str[i] === '{' || str[i] === '[') {
stack.push(str[i]);
}
// If that character is a closing brace, pop from the stack, which will also reduce the length of the stack each time a closing bracket is encountered.
else {
let last = stack.pop();
//If the popped element from the stack, which is the last opening brace doesn’t match the corresponding closing brace in the symbol, then return false
if (str[i] !== symbol[last]) {
return false
};
}
}
// After checking all the brackets of the str, at the end, the stack is not
// empty then fail
if (stack.length !== 0) {
return false
};
return true;
}
function validBraces(braces){
let par =0;
let bra =0;
let cur =0;
for(let i =0; i<braces.length; i++){
if(braces[i]==="("){
par++;
}
if(braces[i]===")"){
par--;
}
if(braces[i]==="["){
bra++;
}
if(braces[i]==="]"){
bra--;
}
if(braces[i]==="{"){
cur++;
}
if(braces[i]==="}"){
cur--;
}
}
if(par<0 || bra<0 || cur<0){
return false;
}
return true;
};
Here is my solution:
var isValid = function (s) {
let charMap = new Map();
for (let i = 0; i < s.length; i++) {
charMap.set(s[i], i);
}
return Boolean(
charMap.get("(") < charMap.get(")") &&
charMap.get("(") % 2 != charMap.get(")") % 2 &&
charMap.get("{") < charMap.get("}") &&
charMap.get("{") % 2 != charMap.get("}") % 2 &&
charMap.get("[") < charMap.get("]") &&
charMap.get("[") % 2 != charMap.get("]") % 2
);
};
Explanation:
In order to achieve a quick and short solution, I have identified the common pattern of validity for opening/closing braces.
The common pattern for opening and closing braces' validity is that if say the opening(closing) stands at the even index in the string, the other one should be odd and vice versa. Example {}, {[]}, {()[]}, {[()]}.
Because we want to avoid a double loop for performance reasons, we are using a Hash Table via Map() to store the character and the index.
An alternative for getting the character's index would be using Array's find or another method, but that would end up in a second loop over the values which we want to avoid.
Finally, once the indexes of and the characters are stored in the charMap, we check whether or not the stored closing/opening characters' standing (odd/even) in the string is not equal, e.g. if '(' is odd the ')' should be even and vice versa.
We check this via the remainder (%) operator, i.e. a number's remainder of 2 is 0 if even.
Additionally, we need to check whether the order of braces is correct, e.g. if '(' is before '}';
The Boolean() function coerces the comparisons in the desired result.
This question already has answers here:
Javascript multiple or condition check
(4 answers)
Javascript If Condition with multiple OR and AND
(7 answers)
Javascript if else statement with multiple or following condition
(3 answers)
Closed 5 years ago.
I am working on a simple function that should return the first element of an array that matches my criteria using a for loop. It keeps returning the first element of the array whether it meets the set criteria or not. Any idea where the bug is here? I also tried the .find() method, same issue.
function wheresTheBeef(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] == 'fillet' || 'strip' || 'sirloin') {
return array[i];
}
else {
return 'there is no beef!'
}
}
}
Your condition is incorrect, change this:
if (array[i] == 'fillet' || 'strip' || 'sirloin') {
for this one:
if (array[i] == 'fillet' || array[i] == 'strip' || array[i] == 'sirloin') {
Reason of the change:
let var1="something";
if (var1) {
console.log("var1 has a truthy value");
}
if (1==0 || "something") {
console.log("condition is true");
}
You need to test each element with the string, because every single non empty string is truthy.
if (array[i] === 'fillet' || array[i] === 'strip' || array[i] === 'sirloin') {
Nearly the same with Array#find and Array#includes
found = array.find(item => ['fillet', 'strip', 'sirloin'].includes(item));
There are 2 problems here.
Your if checking is wrong, because array[i] == 'fillet' || 'strip' || 'sirloin' will always TRUE
And you should not return directly in else branch, otherwise your code logic is only checking for first element
function wheresTheBeef(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] == 'fillet' || array[i] == 'strip' || array[i] == 'sirloin') {
return array[i];
}
else {
continue
}
}
return "there is no beef"
}
so you just need to get rid of the second return statement (and the else). As soon as you return, execution will stop. So if you never return, the loop will continue until it is satisfied.
If you still need the there is no beef statement, you can put it outside the loop. If the loop executes and the condition is never satisfied, then it will proceed to return that statement.
function containsPunctuation(word)
{
var punctuation = [";", "!", ".", "?", ",", "-"];
for(var i = 0; i < punctuation.length; i++)
{
if(word.indexOf(punctuation[i]) !== -1)
{
return true;
}
}
return false;
}
function isStopWord(word, stopWords)
{
for (var i = 0; i < stopWords.length; i += 1)
{
var stopWord = stopWords[i];
if ((containsPunctuation(word)) && (word.indexOf(stopWord) === 0) && (word.length === stopWord.length + 1))
{
return true;
}
else if (word === stopWord)
{
return true;
}
}
return false;
}
At the blockquote, how is containsPunctuation(word) && (word.indexOf(stopWord) === 0? Can someone explain why they are both equal to zero?
I'm also not sure why (word.length === stopWord.length + 1) is used.
I think you are reading the if statement a little bit incorrectly. Not knowing what the isStopWord function is supposed to do I can't tell you what the (word.length === stopWord.length + 1) part is all about.
I can tell you that (containsPunctuation(word)) is its own boolean value, because that function returns a true or false. That part is its own evaluation.
The second part (word.indexOf(stopWord) === 0) is also a complete evaluation. That part has nothing to do with the containsPunctuation function. The indexOf function returns an integer, so it can equal 0.
The third part (word.length === stopWord.length + 1) is checking to see if the length of word is one more than the length of stopWord.
They are all separate evaluations and because you are using && between them all, they all must evaluate as true in order for the code block that follows it to run.
Here are the indexOf docs for string and array:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
--EDIT--
in light of your comment, my guess for the (word.length === stopWord.length + 1) is because the word might contain a punctuation mark that is not included in the stopWord so this if check will only return true if the punctuation is at the end of the word because the indexOf check will only return 0 if the stopword starts at the beginning of the word.
Its simple, if a user enters a number that does not beggin with 6 or 9, he gets error:
console.log($(this).val().charAt(0));
if($(this).val().charAt(0) != 6 || $(this).val().charAt(0) != 9){
x=false;
}else {
x=true;
}
Console.log correctly displays the first character.. that means the value exists..
But no matter if I type 6 or 7 or 9, i will always get false... Why?
Whatever the value of somevar,
somevar!=6 OR somevar!=9
is always true.
The best solution here would probably be a regular expression:
var x = /^[69]/.test($(this).val());
You need to invert the logic conditions as both states cannot possibly be true at the same time, so x is always set to false. Try this:
var chr = $(this).val().charAt(0);
if (chr == '6' || chr == '9') {
x = true;
} else {
x = false;
}
From there you can now see that you don't even need the if condition as you can set x directly, like this:
var chr = $(this).val().charAt(0);
var x = chr == '6' || chr == '9';