# Codewars-Fix String Case

This is from the codewars challenges:

" In this Kata, you will be given a string that may have mixed uppercase and lowercase letters and your task is to convert that string to either lowercase only or uppercase only based on:

• make as few changes as possible.
• if the string contains equal number of uppercase and lowercase letters, convert the string to lowercase."

My code so far : (incomplete I know)

``````function solve(s){
let lcArray = [];
let ucArray = [];
let finalArr = [];
for (let i = 0; i < s.length; i++){
if(s.charCodeAt([i]) >= 97 && s.charCodeAt([i]) <= 122){
lcArray.push(s[i]);

} else if(s.charCodeAt([i]) >= 65 && s.charCodeAt([i]) <= 90) {
ucArray.push(s[i]);
}

if (lcArray.length >= ucArray.length){
finalArr.push(s.toLowerCase);
} else if (lcArray.length < ucArray.length){
finalArr.push(s.toUpperCase)
}
}
}

console.log(solve("HELlo"))
``````

My thought process was to push all lowercase and uppercase letters in their respective arrays and use an if statement (outside the loop but inside the function) to compare lengths. Why do I feel like even though this in theory sounds right, in practice it will not work? My hurdle is once loop is complete how do I return the two arrays? Is this even possible?

Expected result

• if number of upper and lower case characters are equal, return all lower case
• else return all upper case

Steps

• loop through a string
• while looping count number of cases
``````let numOfUpper = 0
let numOfLower = 0

function countCase(){}
function changeStringCase(){} // return string
``````

dont make it anymore complex than it needs to be

1 Like

how do you count for each case without a condition though?? what differentiates an uppercase to lowercase letter? (ie in my original code was the `charCodeAt` method

strings are “array like” objects
loop through string with
a for( ; ; ) loop
loop through the string check
each letter, if the letter is capital
add one to cap if not
subtract one from cap
at the end if cap is zero
do a toLowercase on
the string
checking the char code is
the most obvious way to
determine caps
here is another
if (str[i] == str[i].toLowerCase)
cap + +
else cap - -

1 Like

Managed to work it out with only one new empty array instead of two…

``````function solve(s){
let lcArray = [];
for (let i = 0; i < s.length; i++){
if(s.charCodeAt([i]) >= 97 && s.charCodeAt([i]) <= 122){ // lower case letters
lcArray.push(s[i]);
}
}
if (lcArray.length >= s.length-lcArray.length){
return s.toLowerCase();
} else if (lcArray.length < s.length-lcArray.length){
return s.toUpperCase();
}
}
``````
1 Like
``````<script>
function sd(str) {
cap=0
for(i=0;i<str.length;i++)
if (str[i]==str[i].toLowerCase())cap++
else cap--
if(!cap)str=str.toLowerCase()
}
</script>
``````

``````function sd(str) {
var cap=0;
for(let i=0;i<str.length;i++)
if (str[i]==str[i].toLowerCase())cap++
else cap--
if(!cap)str=str.toLowerCase()
console.log(str)
}
sd('dDdDdDdDdDdD')//logs dddddddddddd
sd('dDdDdDdDdDdDd')//logs dDdDdDdDdDdDd
``````
1 Like

tried this but didn’t work…?

1 Like

amano38 said …
tried this but didn’t work…?

well
you left off …
function sd(str) {
cap=0

1 Like

Problems are easier to solve when you break them down into smaller functions

``````let upper = 0
let lower = 0

// char codes for lower: 65 to 91
// char codes for upper: 97 to 123

function isUpperCase(letter){
let charCode = letter.charCodeAt(0)
let isUpper = charCode >= 97 && charCode <= 123
return isUpper ? true : false

// write a similar function for lower: isLowerCase()

for _ in string:
if isUpperCase(_):
upper += 1
if isLowerCase(_):
lower += 1
``````
1 Like

@amano38, you don’t have to push letters into arrays to count them, you don’t need arrays at all. Here are my suggestions, see if you can turn them into code:

1. Delete all uppercase (or lowercase) characters in the string. It’s important skill to know and there is one useful method for that.
2. Get ratio of resulting string to original string
3. Depending on ratio return original string converted to lowercase or uppercase

Good luck!

3 Likes

I knew you could use Regex! Thank you @snigo!

``````function solve(s) {
let lc = s.replace(/[A-Z]/g, "");
if (lc.length === 0 || lc.length / s.length < 0.5){
return s.toUpperCase();
} else if (s.length % lc.length <= lc.length){
return s.toLowerCase()
}
}
``````

I just dont know why the following ` IF` statement does not work:

``````   if (lc === 0 || s.length % lc.length > lc.length){
return s.toUpperCase();
}
``````

What do you expect this thing to do?
Can you come up with an example that makes this statement true?

in the case I presented if the remainder when you divide `s.length` by length of string once all uppercase letters are removed is greater than length of that same string length than convert all letter in `s` argument to uppercase…

If `lc.length === 0`, what would be the value of `lc.length / s.length < 0.5`?

This will always be true, so you can discard it and return `s.toLowerCase()` in any `else` case

ohh yes! I see what you mean… double handling on both comparison statements gotcha! is there such a thing as coders block? ha!
that becomes such a simple code! thank you for the clarifications