Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir upcase only first letter of a word

Tags:

string

elixir

I've got a string that I need to only upcase the first letter. I also need to preserve the case of any subsequent letters. At first I thought:

String.capitalize("hyperText") 

would do the trick. But in addition to fixing the first letter, it downcases the rest of the letters. What I need to end up with is "HyperText". My initial pass at this is:

<<letter :: utf8, rest :: binary>> = word
upcased_first_letter = List.to_string([letter])
|> String.upcase()

upcased_first_letter <> rest

This works perfectly but it really seems like a lot of verbosity and a lot of work as well. I keep feeling like there's a better way. I'm just not seeing it.

like image 519
jaydel Avatar asked Dec 17 '22 15:12

jaydel


2 Answers

You can use with/1 to keep it to a single expression, and you can avoid List.to_string by using the <<>> operator again on the resulting codepoint:

with <<first::utf8, rest::binary>> <- "hyperText", do: String.upcase(<<first::utf8>>) <> rest

Or put it in a function:

def upcaseFirst(<<first::utf8, rest::binary>>), do: String.upcase(<<first::utf8>>) <> rest
like image 59
Adam Millerchip Avatar answered Mar 01 '23 11:03

Adam Millerchip


One method:

iex(10)> Macro.camelize("hyperText")
"HyperText"

This might be more UTF-8 compatible? Not sure how many letters are multiple codepoints, but this seems a little safer than assuming how many bytes a letter is going to be.

iex(6)> with [first | rest] <- String.codepoints("βool") do
...(6)> [String.capitalize(first) | rest] |> Enum.join()
...(6)> end
"Î’ool"
iex(7)> with [first | rest] <- String.codepoints("😂ool") do
...(7)> [String.capitalize(first) | rest] |> Enum.join()
...(7)> end
"😂ool"
iex(8)>
like image 28
JustGage Avatar answered Mar 01 '23 10:03

JustGage