Can my if statement condition be shortened?

I have a virtual keyboard and in my function to check if the caps lock is on, I also want to check if a letter key following sentence-ending punctuation: ., ?, or !

If so, then I want to use toUpperCase to capitalize the next letter. Here is the code just for that section of the function:

        let len = textBox.value.length;
        let punc = textBox.value;
        if (punc.charAt(len - 1) == '.' || punc.charAt(len - 1) == '?' || punc.charAt(len - 1) == '!') {
          textBox.value = textBox.value + " " + letterkey.toUpperCase();
        } else {
          textBox.value = textBox.value + letterkey.toLowerCase();

Where textBox is the textarea where the virtual keyboard adds the characters. Is the if condition too lengthy, or is that fine?

Just as regards the original question about making the if condition shorter:

The first thing that jumps out is that instead of doing the lookup punc.charAt(len - 1) three times, you could put that in a variable. You might also consider looking at .includes().

Is the if condition too lengthy, or is that fine?

It does the job and is coherent code. You don’t have any extraneous logic there. I think it is fine.

That being said, it could be cleaned up a little. For one thing, you could abstract it into a function, like:

const getIsTerminalPunctuation = char => char === '.' || char ===  '?' || char === '!';

// ...

if (getIsTerminalPuntuation(punc.charAt(len - 1))) {

That is a little cleaner. I also like it because it calls that charAt function only once.

You could also do something like

if (['.', '?', '!'].includes(punc.charAt(len - 1)) {

or put that in a function. Or store that array in a constant somewhere.

Those are options for cleaning it up a bit.

But I also don’t think what you have is atrocious (except maybe calling that method three times instead of once).

Is there a reason you use String.charAt() instead of simply string[index]?
Another way to put your condition could be:

let lastChar=punc[len-1]
if (/[?!.]/.test(lastChar)) { ... }

Regex is prolly the best way to manipulate string. You could even go without the condition statement in your code and directly look for punctuation marks in a string and uppercase following letters

edit: had swapped the test parameter and the object its applied on

1 Like

I’m not familiar with includes - let me look into that - thanks!

I was thinking about putting those 3 in an array - let me try that. Thanks!

I’ve been watching Regex videos and I can’t believe I didn’t think of that. Thanks!

Yeah, I always forget regex. It’s arcane but it also sometimes does very powerful things with minimal code.

No need to separate the last char, you can just do it with the regex:

if (/[!?.]$/gm.test(punc)) {

I think that would work.

Addendum: I’m not sure if you need/want the g and m flag - I was just riffing. You’d have to confirm, depending on your needs.

Regular expressions would be my go-to, especially if you want to do something like check for all non-alphanumeric characters. I know that a lot of people get frustrated by them though.

1 Like

This works like a charm:

['.', '?', '!'].includes(punc.charAt(len - 1))

That seemed like the easiest solution. I’ll have to look for some examples of .includes() since I’m not too familiar with it.

I’m starting to get comfortable with them.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.