177

I'm looking through the lodash docs and other Stack Overflow questions - while there are several native JavaScript ways of accomplishing this task, is there a way I can convert a string to title case using purely lodash functions (or at least existing prototypal functions) so that I don't have to use a regular expression or define a new function?

e.g.

This string ShouLD be ALL in title CASe

should become

This String Should Be All In Title Case
Community
  • 1
  • 1
brandonscript
  • 68,675
  • 32
  • 163
  • 220
  • 2
    https://github.com/lodash/lodash/issues/1528 – Alexandre Thebaldi Jun 28 '16 at 19:16
  • 11
    you can do same thing from HTML also, **style="text-transform: capitalize"** – Apurv Chaudhary Oct 09 '18 at 10:41
  • The reason why this doesn't exist in `lodash` is because different use cases expect different results from it. When `titleCase`-ing french names (e.g: `jean-pierre`), the expected result is `Jean-Pierre`. But when `titleCase`-ing npm package names, the expected result from `some-package-name` is `Some Package Name`. – tao Feb 17 '22 at 23:02
  • 1
    Since `lodash` doesn't offer a good solution because of special characters issue, here's another ready to use package for that: `titleCase(str.toLowerCase())` from https://www.npmjs.com/package/title-case . Tis properly handles special characters and capitalization after `-` and `'` – maganap Nov 26 '22 at 15:11

16 Answers16

319

This can be done with a small modification of startCase:

_.startCase(_.toLower(str));

console.log(_.startCase(_.toLower("This string ShouLD be ALL in title CASe")));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
4castle
  • 32,613
  • 11
  • 69
  • 106
  • 4
    `_.startCase("aaa BBB ccc") === "Aaa BBB Ccc"` – Brandon Jun 28 '16 at 19:21
  • @Brandon How about now? – 4castle Jun 28 '16 at 19:23
  • 2
    I like it. I didn't know about `startCase`. – Brandon Jun 28 '16 at 19:23
  • 3
    _.startCase("camelString") === "Camel String" but _.startCase(_.toLower("camelString")) === "Camelstring" seems like lodash needs a titleCase method – aristidesfl Sep 15 '16 at 11:08
  • @aristidesfl To handle the situation where the input was camelCase, you would need to run it through [`_.lowerCase`](https://lodash.com/docs/4.15.0#lowerCase) first instead of `_.toLower`. But yeah, it's too bad there isn't a function that just goes straight to it. – 4castle Sep 15 '16 at 14:56
  • @aristidesfl But it would break the string `'This string ShouLD be ALL in title CASe'` so I didn't do it. Since `ShouLD` would become `Shou L D` – 4castle Sep 15 '16 at 15:08
  • @4castle true. however I suspect that in most situations where you want to display title case, you don't start with random CrAzY CaSE. Most often one wants to convert from other type of case, and the suggested method handles those better (upper, camel, pascal, snake) http://stackoverflow.com/a/39510222/1445812 – aristidesfl Sep 18 '16 at 17:32
  • @aristidesfl Right, but this question is about a CrAzY CaSE, so that answer does not answer the question. – 4castle Sep 18 '16 at 17:35
  • @4castle even though the question is not specifically about CraZy CaSE, the provided example is CrAzY CaSE, so fair enough. Can't get tired of typing in CrAzY CaSE. – aristidesfl Sep 22 '16 at 17:33
  • 9
    I like this, however, it removes characters such as `:`, that is a problem. – JabberwockyDecompiler May 25 '18 at 15:04
  • 4
    It does not work for first names with accent (Spanish "Martínez Cortés Peña" becomes "Martinez Cortes Pena") or with hyphens (French "Jean-Louis" becomes "Jean Louis"). Same goes for any "*Case" functions of lodash – Flo May 10 '19 at 20:29
  • 1
    We should avoid _ imports (import _ from 'lodash'`) this simply passes a bad practice to people – Leap Hawk Jan 21 '21 at 09:05
  • This will work for the example in the question however, it's important to note that it removes special characters like underscores and hyphens from the string. – Piyush Balapure Jan 19 '22 at 07:10
  • this is not title case /: words like "the" get capitalized to "The". – John Miller May 04 '23 at 18:17
  • @JohnMiller Title case has many different definitions. See the various rules here: https://capitalizemytitle.com/#capitalizationrules The OP specified they just want to uppercase the first letter of every word. – 4castle May 09 '23 at 12:30
74
_.startCase(_.camelCase(str))

For non-user-generated text, this handles more cases than the accepted answer

> startCase(camelCase('myString'))
'My String'
> startCase(camelCase('my_string'))
'My String'
> startCase(camelCase('MY_STRING'))
'My String'
> startCase(camelCase('my string'))
'My String'
> startCase(camelCase('My string'))
'My String'
aristidesfl
  • 1,310
  • 10
  • 15
49

with lodash version 4.

_.upperFirst(_.toLower(str))

James Nguyen
  • 722
  • 6
  • 16
31
'This string ShouLD be ALL in title CASe'
  .split(' ')
  .map(_.capitalize)
  .join(' ');
CD..
  • 72,281
  • 25
  • 154
  • 163
  • 2
    Definitely the most concise, like it. Obviously still requires splitting into an array, but that's still the shortest and sweetest solution from what I can tell. Also, per the issue 1528 that @AlexandreThebaldi indicated, probably should use `upperFirst` instead of `capitalize`. – brandonscript Jun 28 '16 at 19:19
  • ... but _.startCase definitely wins :) – brandonscript Jun 28 '16 at 19:25
  • 5
    `_.startCase` removes punctuation. Example `_.startCase('first second etc...` returns the string `First Second Etc` – LuckyStarr Jul 12 '17 at 14:55
  • This was better for my use case as `startCase` converts everything to a blank for example `user_name` will be `User Name`, and i only wanted `User_name` like the `text-transform: capitalize` property of CSS – gonzarodriguezt Aug 16 '19 at 20:05
18

There are mixed answers to this question. Some are recommending using _.upperFirst while some recommending _.startCase.

Know the difference between them.

i) _.upperFirst will transform the first letter of your string, then string might be of a single word or multiple words but the only first letter of your string is transformed to uppercase.

_.upperFirst('jon doe')

output:

Jon doe

check the documentation https://lodash.com/docs/4.17.10#upperFirst

ii) _.startCase will transform the first letter of every word inside your string.

_.startCase('jon doe')

output:

Jon Doe

https://lodash.com/docs/4.17.10#startCase

Vishal Shetty
  • 1,618
  • 1
  • 27
  • 40
  • Yep, but what about mixed case strings? Neither of these will make ‘jOn DoE’ into ‘Jon Doe’ without `_.lower()`. – brandonscript Jun 27 '18 at 06:13
7

That's the cleanest & most flexible implementation imo from testing it on my own use cases.

import { capitalize, map } from "lodash";

const titleCase = (str) => map(str.split(" "), capitalize).join(" ");

// titleCase("ALFRED NÚÑEZ") => "Alfred Núñez"
// titleCase("alfred núñez") => "Alfred Núñez"
// titleCase("AlFReD nÚñEZ") => "Alfred Núñez"
// titleCase("-") => "-"
alewis729
  • 249
  • 3
  • 8
4

From https://github.com/lodash/lodash/issues/3383#issuecomment-430586750

'JHON&JOHN C/O DR. BLah'.replace(/\w+/g, _.capitalize);

result:

'Jhon&John C/O Dr. Blah'
Rafal Enden
  • 3,028
  • 1
  • 21
  • 16
3

Here's a way using ONLY lodash methods and no builtin methods:

_.reduce(_.map(_.split("Hello everyOne IN the WOrld", " "), _.capitalize), (a, b) => a + " " + b)
Brandon
  • 38,310
  • 8
  • 82
  • 87
3

Below code will work perfectly:

var str = "TITLECASE";
_.startCase(str.toLowerCase());
2

This can be done with only lodash

properCase = string =>
        words(string)
            .map(capitalize)
            .join(' ');

const proper = properCase('make this sentence propercase');

console.log(proper);
//would return 'Make This Sentence Propercase'
1
 var s = 'This string ShouLD be ALL in title CASe';
 _.map(s.split(' '), (w) => _.capitalize(w.toLowerCase())).join(' ')

Unless i missed it, lodash doesnt have its own lower/upper case methods.

agmcleod
  • 13,321
  • 13
  • 57
  • 96
1
const titleCase = str =>
  str
    .split(' ')
    .map(str => {
      const word = str.toLowerCase()
      return word.charAt(0).toUpperCase() + word.slice(1)
    })
    .join(' ')

You can also split out the map function to do separate words

Luke Robertson
  • 1,592
  • 16
  • 21
0

Not as concise as @4castle's answer, but descriptive and lodash-full, nonetheless...

var basicTitleCase = _
    .chain('This string ShouLD be ALL in title CASe')
    .toLower()
    .words()
    .map(_.capitalize)
    .join(' ')
    .value()

console.log('Result:', basicTitleCase)
console.log('Exact Match:' , basicTitleCase === 'This String Should Be All In Title Case')
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
m-a-r-c-e-l-i-n-o
  • 2,622
  • 18
  • 26
  • I'd guess that the verbosity and length of the answer makes it almost undesirable. I didn't downvote, but it wouldn't be my first choice. – brandonscript Jun 29 '16 at 02:04
0

Here's another solution for my use case: "devil's backbone"

Simply:

function titleCase (str) {
  return _.map(str.split(' '), _.upperFirst).join(' ');
}

Using startCase would remove the apostrophe, so I had to work around that limitation. The other solutions seemed pretty convoluted. I like this as it's clean, easy to understand.

albertpeiro
  • 356
  • 4
  • 14
-3

you can simply use the lowdash capitalize methode , it Converts the first character of string to upper case and the remaining to lower case. https://lodash.com/docs/#capitalize

const str = 'titlecase this string ';
_.capitalize(str); //Titlecase This String
-4

with lodash 4, you can use _.capitalize()

_.capitalize('JOHN') It returns 'John'

See https://lodash.com/docs/4.17.5#capitalize for details