I had a friend recommend me to make a spongebob meme generator for some of the mocking shenaningans we engage in, in our discord chat.

Thought i'd give it a shot as it seemed like quite an easy task. Just creating text that each character alternatives between it's uppcase and lowercase.

Before I get into it, here's a simple demo of the end result:

So initially I came up with this very simple one liner.

const meme = (text) => [...text].map((char, index) => index % 2 === 0 ? char.toUpperCase() : char.toLowerCase()).join('');
1

For the purpose of explanation i'll expand this:

const meme = [...text].map((char, index) => {
    let character;
    if (index % 2 === 0) {
        character = char.toUpperCase();
    } else {
        character = char.ToLowerCase();
    }
    return character;
}).join('');
1
2
3
4
5
6
7
8
9

What it does is:

  1. Transforms the text variable into an array/iterable with the power of ES6 spread syntax [...text] with each array element now being a character of the initial string.
  2. Then uses the Array.prototype.map() method for arrays to iterate over each element/character.
  3. We then have an if statement/ternary to decide if we should capitalise the character or lower case it.
  4. Array.prototype.map() provides us with the index we are on as part of its callback arguments, so we simply use the % modulus operator to determine if the index is an even number or an odd number. If it is an even number, we simply capitalise the character (to ensure the 0th index / first character is always capitalised) else we lower case it.
  5. We then return the modified character variable to pass to the new array we will create.
  6. Finally we use the Array.prototype.join() method to join the array back together and create our string.

# Seems pretty easy right? Yeah!

But me being that guy who strives for perfection, I noticed this still has some flaws, because all it does is simply alternate each character with its upper / lower case value.

For example it doesn't account for spaces, symbols or any other non alphabetic character, so it will technically attempt to upper / lower case any non alphabetic character too, which could result in the subsequent letter being the same case as the letter before a space. e.g the string hello world will result in HeLlO WoRlD or 1234 HELLO' WORLD resulting in 123 HeLlO' wOrLd

# So back to the drawing board..

I had several ideas of how to solve this.. but ultimately this is what I came up with:

let index = 0;
const meme = (words) => [...words].map((char) => {
    if (!/^[a-zA-Z()]$/.test(char)) {
        return char;
    }
    const memedLetter = index % 2 === 0 ? char.toUpperCase() : char.toLowerCase();
    index++;
    return memedLetter;
}).join('');
1
2
3
4
5
6
7
8
9
10

And the explanation:

  1. First I wanted to track what action I made "last", whether I capitalised a letter or lower cased it, so I created a simple index variable out of the scope of the function.
  2. Again we use ES6 spread syntax to convert the string into an array of all the characters it has [...words].
  3. We loop over that again using the Array.prototype.map() method.
  4. Now here's where things change, now instead of deciding whether to upper/lower case a character, we first use a little bit of regex to check if the current char being passed in is actually an alphabetic character.
    • If it is not an alphabetic character, we simply just return it back to our .map() method.
    • If it is an alphabetic character, we perform the same method we applied above, but only difference is we're using the index variable we defined outside of the .map() scope. We then increment that variable after we have applied the upper/lower case value to the memedLetter variable.
  5. We now have an index counter that is incremented whenever a character has been either capitalised or lower cased, which we can use to determine if we need to capitalise a character or lower case it by simply checking if the index value is even or odd.
  6. Finally we Array.prototype.join() our array of characters back together to create our slightly modified initial string.

A very simple task for almost no benefit, but very fun and a little bit more challenging than meets the eye.

If you've noticed any errors in this article, or have any suggestions for how I can improve this or make it better, feel free to dm me and let me know! "ThIs Is My FiRsT bLoG pOsT" 😩