Home > Software design >  How to check existence and amount of certain characters within a string (e.g. 'x'/'X&
How to check existence and amount of certain characters within a string (e.g. 'x'/'X&

Time:05-01

I was on code wars (fundamentals) and there was a kata that asked me to make a program that allows you to see if amount of 'x' and 'o' are the same (for example 'xXXooO' should return true and 'xXxxO' should return false).

Using my best knowledge about coding (which is a little) I built this code but it wouldn't work.

function XO(str) {
  let string = str;
  const o = string.match(/O/g)   string.match(/o/g);
  const x = string.match(/X/g)   string.match(/x/g);
  if (o.length != x.length) {
    return true;
  } else {
    return false;
  }
}

Please tell me what is wrong with my code.

This part is after I updated.

I updated my code but it says that null is not an object. I updated the variables too, and I don't think that is the reason why.

function XO(str) {
  let string = str;
  const largeO = string.match(/O/g);
  const smallO = string.match(/o/g);
  const largeX = string.match(/X/g);
  const smallX = string.match(/x/g);
  const oCombined = largeO.length   smallO.length;
  const xCombined = largeX.length   smallX.length;
  if (oCombined = xCombined) {
    return true;
  } else {
    return false;
  }
}
console.log(XO("OxX"));

CodePudding user response:

One needs to use an regex' i modifier (or flag) for case insensitive matches of 'x'/'X' and 'o'/'O'.

And of cause one needs to handle the null return value of a failing match method which for the next provided example code is taken care of by Optional chaining / ?. and the Nullish coalescing operator / ??.

function isXAndOWithSameAmount(value) {
  // always assure a string type  
  value = String(value);

  // in case of a `null` value ... ...count is -1.
  const xCount = value.match(/x/gi)?.length ?? -1;

  // in case of a `null` value ... ...count is -2.
  const oCount = value.match(/o/gi)?.length ?? -2;

  // thus the return value for neither an 'x'/`X`
  // match nor an 'o'/`O` match will always be `false`.
  return (xCount === oCount);

  // in order to achieve another (wanted/requested)
  // behavior one needs to change both values after
  // the nullish coalescing operator accordingly.
}

console.log(
  "isXAndOWithSameAmount('xXXooO') ..?",
  isXAndOWithSameAmount('xXXooO')
);
console.log(
  "isXAndOWithSameAmount('xXoXooOx') ..?",
  isXAndOWithSameAmount('xXoXooOx')
);

console.log(
  "isXAndOWithSameAmount('xXxxO') ..?",
  isXAndOWithSameAmount('xXxxO')
);
console.log(
  "isXAndOWithSameAmount('xOoXxxO') ..?",
  isXAndOWithSameAmount('xOoXxxO')
);

console.log(
  "isXAndOWithSameAmount('') ..?",
  isXAndOWithSameAmount('')
);
console.log(
  "isXAndOWithSameAmount('bar') ..?",
  isXAndOWithSameAmount('bar')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

One of cause can achieve the same behavior by casting the result of match and an optionally chained ?.length into an integer value via parseInt which will return either an (integer) number value grater than zero or the NaN value.

function isXAndOWithSameAmount(value) {
  // always assure a string type  
  value = String(value);

  // making use of optional chaining and `parseInt`
  // which will result in (integer) number values
  // grater than zero or the `NaN` value.
  const xCount = parseInt(value.match(/x/gi)?.length);
  const oCount = parseInt(value.match(/o/gi)?.length);

  // since a `NaN` value is not equal to itself
  // the return value for neither an 'x'/`X` match
  // nor an 'o'/`O` match will always be `false`.
  return (xCount === oCount);
}

console.log(
  "isXAndOWithSameAmount('xXXooO') ..?",
  isXAndOWithSameAmount('xXXooO')
);
console.log(
  "isXAndOWithSameAmount('xXoXooOx') ..?",
  isXAndOWithSameAmount('xXoXooOx')
);

console.log(
  "isXAndOWithSameAmount('xXxxO') ..?",
  isXAndOWithSameAmount('xXxxO')
);
console.log(
  "isXAndOWithSameAmount('xOoXxxO') ..?",
  isXAndOWithSameAmount('xOoXxxO')
);

console.log(
  "isXAndOWithSameAmount('') ..?",
  isXAndOWithSameAmount('')
);
console.log(
  "isXAndOWithSameAmount('bar') ..?",
  isXAndOWithSameAmount('bar')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

  • Related