Don't understand why I am getting this error?

Below is my solution for this codewars challenge

function solve(s){
  let upper = s.match(/[A-Z]/g);
  let lower = s.match(/[a-z]/g);
  if(upper && upper.length > lower && lower.length){
    return s.toUpperCase();
  } 
  return s.toLowerCase();
}

but it is coming up with the below error:

These are the tests performed:

describe(“Basic tests”, function(){
Test.assertEquals(solve(“code”),“code”);
Test.assertEquals(solve(“CODe”),“CODE”);
Test.assertEquals(solve(“COde”),“code”);
Test.assertEquals(solve(“Code”),“code”);
});

Basically it is has a problem converting to uppercase but not lowercase, but not sure why?

Try manually setting upper and lower to different example arrays, and examine the result of this expression. I think you’ll be surprised by the outcome.

1 Like

Sorry, I don’t understand what it means to ‘manually set to different example arrays’??

I eventually managed to make it pass by adding a line addressing the null:

function solve(s){
  let upper = s.match(/[A-Z]/g);
  let lower = s.match(/[a-z]/g);
  if(upper == null){
    return s.toLowerCase();
  }
  if(upper.length > lower.length){
    return s.toUpperCase();
  } 
  return s.toLowerCase();
}

But this doesn’t look ideal :confused:

Also in the console the original code worked fine, but just not in codewars…pretty confused

I just meant to try things like this:

let upper = ['C','O','D']
let lower = ['e']
console.log(upper && upper.length > lower && lower.length)

and to substitute different values for upper and lower. You can do all of that inside the function too, but sometimes it’s easier to debug line by line without it all being inside a function. :slight_smile:

I think the original issue was that the conditional was being evaluated left to right rather than the items around the &&s being grouped. So it was evaluating this way:

// Assume upper == ['C', 'O', 'D'] and lower == ['e']
upper && upper.length // 3
upper && upper.length > lower // equivalent to "3 > lower" which is actually false (oh no!)
upper && upper.length > lower && lower.length // equivalent to "false && 1" which is false

I suspect if you add some ()s around the && terms of your original solution, it will behave as expected. Greater than / less than comparisons get pretty weird when arrays are compared – JS actually converts the array to a string value first.

2 Likes

You’re right, that did work by adding the brackets.
Would have never guessed to do that. Will make a note of this!
Thanks for the tip about debugging!

1 Like