1

I'm new to JavaScript and not sure why my code isn't working. I'm trying to return true if there are an equal amount of x's and o's, and return false if there are not. My code works for all inputs except "x" and "o". Any help is appreciated!

My code:

function ExOh(str) { 
 var x = str.match(/[^x$]/gi);
  var o = str.match(/[^o$]/gi);
  if (x.length == o.length) {
    return true;
  }
  else {
    return false;
  }
}

4 Answers 4

2

Your regexps allow any characters other than x/y and $. You must have meant /x/gi and /o/gi.

function ExOh(str) { 
 var x = str.match(/x/gi) || "";
  var o = str.match(/o/gi) || "";
  if (x.length === o.length) {
    return true;
  }
  else {
    return false;
  }
}
alert(ExOh("zzz"));
alert(ExOh("oozzzxx"));

Note that negated character classes like [^x] match all characters other than those inside the square brackets. $ inside them is treated as a literal dollar sign.

Typing a caret after the opening square bracket negates the character class. The result is that the character class matches any character that is not in the character class. Unlike the dot, negated character classes also match (invisible) line break characters. If you don't want a negated character class to match line breaks, you need to include the line break characters in the class. [^0-9\r\n] matches any character that is not a digit or a line break.

Sign up to request clarification or add additional context in comments.

4 Comments

This still raises an error if you only pass a single 'x' or 'o'. The str.match returns null and the conditional breaks when calling .length on the null value.
I'm curious why you would not have corrected this to return x.length === o.length;. Also, I think you want || [], not || "".
I am sorry, I was focused on the main regex issue. I implemented the changes. Sure, === will also check the type and the value, and match result is better checked for null. Actually, "" and [] yield the same result.
Wow, this is all super helpful. Apparently there is lots more for me to learn about regexps!
0

You need to set the value to something other than null if the str.match doesn't actually match something. You can't call length on null. Use the or operator to set the value to an empty string in your variable declaration.

function ExOh(str) { 
 var x = str.match(/[^x$]/gi) || '';
 var o = str.match(/[^o$]/gi) || '';
 if (x.length == o.length) {
    return true;
 }
 else {
   return false;
 }
}

I hope this helps

2 Comments

This doesn't solve the basic problem, which is that the ^ is in the wrong place. Did you test it?
From OP's question it was raising when one of the values didn't match. Yes, I tested in the console.
0

Here's a solution for checking that the number of two characters is the same.

// How many 'x' characters occur in a string?
function numberOf(str, x) {
  var matches = str.match(new RegExp(x, 'g'));
  return matches ? matches.length : 0;
}

// Create a function to check if the number of x's and o's in 
// a string are the same.
function same(x, o) {
  return function(str) {
    return numberOf(str, x) === numberOf(str, o);
  };
}

var isSame = same('x', 'o');
isSame('xxooabc');

Comments

0

Remove ^ and $ from your regex , [^o$] match a single character not o or $. You just need to use /x/ and /o/ and flags ig, i for ignoring case and g for global match.

Typing a caret after the opening square bracket negates the character class. The result is that the character class matches any character that is not in the character class. Unlike the dot, negated character classes also match (invisible) line break characters. If you don't want a negated character class to match line breaks, you need to include the line break characters in the class. [^0-9\r\n] matches any character that is not a digit or a line break. ( Taken from http://www.regular-expressions.info/charclass.html )

Update : Add (!x && !o) and x && o in condition for avoiing error when zero matches are there. (!x && !o) for when both are not present.x && o will help only to check the condition x.length == o.length when both x and o are defined.

var div = document.getElementById('res');

function ExOh(str) {
  var x = str.match(/x/gi);
  var o = str.match(/o/gi);
  if ((!x&&!o) || x && o && x.length == o.length) {
    res.innerHTML = 'Same';
    return true;
  } else {
    res.innerHTML = 'Not Same';
    return false;
  }
}
<input type=text oninput="ExOh(this.value)">
<div id=res></div>

2 Comments

This will fail to match zero o's and zero x's, which should probably return the value of true.
Input of "abc" returns "Not Same" when the answer should be "Same".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.