DEV Community

dev.to staff
dev.to staff

Posted on

18 3

Daily Challenge #190 - capitalizeFirstLast

For this challenge, you will have to write a function called capitalizeFirstLast or capitalize_first_last. This function will capitalize the first and last letter of each word, and lowercase what is in between.

capitalizeFirstLast "and still i rise" -- "AnD StilL I RisE"

Rules:

  • The function will take a single parameter, which will be a string.
  • The string can contain words separated by a single space.
  • Words are made of letters from the ASCII range only.
  • The function should return a string.
  • Only the first and last letters are uppercased.
  • All the other letters should be lowercased.

Examples:

capitalizeFirstLast "and still i rise"               -- "AnD StilL I RisE"
capitalizeFirstLast "when words fail music speaks"   -- "WheN WordS FaiL MusiC SpeakS"
capitalizeFirstLast "WHAT WE THINK WE BECOME"        -- "WhaT WE ThinK WE BecomE"
capitalizeFirstLast "dIe wITh mEMORIEs nOt dREAMs"   -- "DiE WitH MemorieS NoT DreamS"
capitalizeFirstLast "hello"                          -- "HellO"

Good luck!


This challenge comes from aminnairi here on DEV. Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (24)

Collapse
 
willsmart profile image
willsmart • Edited

An easy option is to start off by lowercasing the whole thing...
(JS)

capitalizeFirstLast = s => s.toLowerCase().replace(/\b\w|\w\b/g, c => c.toUpperCase())

Regex matches single letters preceded by a word boundary or followed by a word boundary.

Running through the examples:

[
  "and still i rise",
  "when words fail music speaks",
  "WHAT WE THINK WE BECOME",
  "dIe wITh mEMORIEs nOt dREAMs",
  "hello"
].map(s => `"${s}" -> "${capitalizeFirstLast(s)}"`).join("\n")

>> 

"and still i rise" -> "AnD StilL I RisE"
"when words fail music speaks" -> "WheN WordS FaiL MusiC SpeakS"
"WHAT WE THINK WE BECOME" -> "WhaT WE ThinK WE BecomE"
"dIe wITh mEMORIEs nOt dREAMs" -> "DiE WitH MemorieS NoT DreamS"
"hello" -> "HellO"
Collapse
 
khauri profile image
Khauri

Nice! Super clean.

Collapse
 
willsmart profile image
willsmart

Thanks!

Collapse
 
khauri profile image
Khauri • Edited

Javascript + Regex "One" liner.

function capitalizeFirstLast(string) {
  return string.replace(/(\w)((\w*)(\w))?/g, (_, a, __, b, c) => [a.toUpperCase(), b && b.toLowerCase(), c && c.toUpperCase()].filter(Boolean).join(''))
}

Click here if you're curious what the regular expression does

Collapse
 
tails128 profile image
Tails128 • Edited

The most straightforward way to fix this is probably to do something as:

export const capitalizeFirstLast = (inputString: string): string => 
    inputString
        .split(' ')
        .reduce((accumulator: string, entry: string) =>
            { 
                let fixedWord: string = capitalizeFirstLastInWord(entry);

                return `${accumulator} ${fixedWord}`;
            }, "");


const capitalizeFirstLastInWord = (word: string) =>
    word.charAt(0).toUpperCase()
    + word.slice(1, -1).toLowerCase()
    + word.charAt(entry.length -1).toUpperCase()

but probably there are better ways to do this :P

EDIT: Ofc some tuning is required if we also accept punctuation and, numbers or any other characters of sort, but the requirements state letters, so...

Collapse
 
aminnairi profile image
Amin

I think there are a couple mistakes in your solution.

In your capitalizeFirstLastInWord function, you are using the variable entry. I think you meant word?

And in your capitalizeFirstLast function, you are using an undefined variable fixedWord. Maybe this was the return value of your previous function call?

Other than that, I really like how you used the reduce method to solve this one!

Collapse
 
tails128 profile image
Tails128 • Edited

You are 100% right, I did some last-minute refactoring and I was a bit distracted! :P

I will edit it for future readers :)

About the reduce part: The idea came because last year I was able to work with an
awesome team which enforced very good practices & a very cool "implementation"
of functional programming, I miss that team a lot!

Collapse
 
interludedesign profile image
Chris Swann • Edited

First try in Ruby, I think this can be done without splitting and rejoining.

def capitalizeFirstLast(string)

    string.split(' ').each do |word|
        word.downcase!
        word.sub!(/\A./) {|match| match.upcase} # First Char
        word.sub!(/.\z/) {|match| match.upcase} # Last Char
    end.join(' ')

end

puts capitalizeFirstLast "tHIs is my string"
# => ThiS IS MY StrinG
Collapse
 
nombrekeff profile image
Keff

Cool, many ways of doing this.

This is what I came up with:

function capitalizeFirstLast(string = "") {
  const _firstLastWord = word => {
    if (!word || word.length <= 1) {
      return word.toUpperCase();
    }

    let len = word.length;
    const upperAt = i => word.charAt(i).toUpperCase();
    return `${upperAt(0)}${word.substr(1, len - 2)}${upperAt(len - 1)}`;
  };

  return string.length
    ? string
        .toLowerCase()
        .split(" ")
        .map(_firstLastWord)
        .join(" ")
    : string;
}
Collapse
 
viktordimitrievski profile image
Viktor

First & Fast & Last try with JS

capitalizeFirstLast = sentence => {
    var arrWords = sentence.toLocaleLowerCase().split(" ");
    var newArrWords = [];

    arrWords.forEach((x,i)=> {
        var wordLength = x.length;
        if(wordLength > 2){
            newArrWords.push(x.charAt(0).toUpperCase() + x.substr(1,wordLength-2) + x.charAt(wordLength - 1).toUpperCase());
        }
        else{
            newArrWords.push(x.toUpperCase());
        }
    });
return newArrWords.join(" ");
}
Collapse
 
vidit1999 profile image
Vidit Sarkar

C++

string capitalizeFirstLast(string s){
    string modifiedString = "";
    for(int i=0;i<s.length();i++){
        if(i==0 || (i>0 && s[i-1]==' ') || (i<s.length()-1 && s[i+1] == ' ') || i==s.length()-1){
           modifiedString += char(toupper(s[i]));
        }
        else{
            modifiedString += char(tolower(s[i]));
        }
    }
    return modifiedString;
}

Python one liner

def capitalizeFirstLast(s):
  return  " ".join([word[0].upper()+word[1:-1].lower()+(word[-1].upper() if len(word)>1 else "") for word in s.split()])
Collapse
 
sabbin profile image
Sabin Pandelovitch • Edited

Another JS example

const capitalizeFirstAndLast = string => {
    const splitString = str => str.split(' ');
    const fixWords = array =>
        array.map(v =>
            v.length < 2
                ? v.toUpperCase()
                : `${v.charAt(0).toUpperCase()}${v.toLowerCase().substr(1, v.length - 2)}${v.charAt(v.length - 1).toUpperCase()}`
        );
    const joinString = array => array.join(' ');

    return string
        |> splitString
        |> fixWords
        |> joinString
};

//TESTING
const tests = [
    "and still i rise",
    "when words fail music speaks",
    "WHAT WE THINK WE BECOME",
    "hello",
];

console.log(tests.map(capitalizeFirstAndLast));
/*
[
  'AnD StilL I RisE',
  'WheN WordS FaiL MusiC SpeakS',
  'WhaT WE ThinK WE BecomE',
  'HellO'
]
*/
Collapse
 
navdeepsingh profile image
Navdeep Singh • Edited
console.clear();
const capitalizeFirstLast = (str) => {
  let strArr = str.split(" ");
  let parseStr = strArr.map(item => {
        itemArr = [...item];
        midStr = itemArr.slice(1,itemArr.length-1).join('');
        return item.length > 1 ? item[0].toUpperCase() + midStr.toLowerCase() + item[item.length-1].toUpperCase() : item[0].toUpperCase();      
  }).join(' ');
  console.log(parseStr);  
}
capitalizeFirstLast('my name is NAVDEEP singh')

JSBin Link

Collapse
 
jehielmartinez profile image
Jehiel Martinez

JAVASCRIPT ANSWER

function capitalizeFirstLast(str) {
    return str.replace(/[^\s]+/g, (match) => {
        replaceStr = '';
        const len = match.length;

        for(i=0; i<len; i++){
            if(i === 0 || i === len-1){
                replaceStr = replaceStr + match[i].toUpperCase();
            } else {
                replaceStr = replaceStr + match[i].toLowerCase();
            }
        }

        return replaceStr
    });
};

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay