DEV Community

dev.to staff
dev.to staff

Posted on

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!

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
 
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
 
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
 
amcmillan01 profile image
Andrei McMillan

python

import re def to_uc(match_group): return match_group.group(0).upper() def capitalize_first_last(in_str): in_str = in_str.lower().strip() in_str = re.sub(r'\s+', ' ', in_str) in_str = re.sub(r'(^[a-z])', to_uc, in_str) in_str = re.sub(r'([a-z]$)', to_uc, in_str) in_str = re.sub(r'(\s[a-z])', to_uc, in_str) in_str = re.sub(r'([a-z]\s)', to_uc, in_str) print in_str # ----- capitalize_first_last('and still i rise') capitalize_first_last('when words fail music speaks') capitalize_first_last('WHAT WE THINK WE BECOME') capitalize_first_last('dIe wITh mEMORIEs nOt dREAMs') capitalize_first_last('hello') # ----- # AnD StilL I RisE # WheN WordS FaiL MusiC SpeakS # WhaT WE ThinK WE BecomE # DiE WitH MemorieS NoT DreamS # HellO  
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 }); }; 
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