5

I'm trying to proper case a string in javascript - so far I have this code: This doesn't seem to capitalize the first letter, and I'm also stuck on how to lowercase all the letters after the first letter.

function titleCase(str) {
  var newstr = str.split(" ");
  for(i=0;i<newstr.length;i++){
    newstr[i].charAt(0).toUpperCase();

  }
   newstr = newstr.join(" ");
   return newstr;
}  

To be clear, I want every single word in the sentence to be capitalized.

natalie
  • 99
  • 1
  • 3
  • 7
  • 2
    You just missed the assignment of newstr[i] to the new value first letter uppercased. And lowercase the str before split it. – Frankely Diaz Jul 18 '15 at 20:31
  • http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript - good and elegant solution – Reflective Jul 18 '15 at 20:38
  • 1
    @Reflective Very similar but not quite identical question. The author of this question wants initial caps with the rest of the word lowercase, whereas in your linked question the author wants initial caps with the rest of the word's case unchanged. – Maximillian Laumeister Jul 18 '15 at 20:40
  • @natalie I have found a similar question, http://stackoverflow.com/questions/4878756/javascript-how-to-capitalize-first-letter-of-each-word-like-a-2-word-city you can use regex too ! – Nishant Jul 18 '15 at 20:43

14 Answers14

5

One of the cleanest ways I can come up with, using ES6, while still lacking a proper .capitalize() string prototype method:

let sent = "these are just some words on paper"
sent.split(' ').map ( ([h, ...t]) => h.toUpperCase() + t.join('').toLowerCase() )

Uses destructuring on array element strings to obtain head and tail via spread operator (making tail a sequence of characters) which are first joined before coerced to lower case. Or you could replace that with a s => s[0].toUpperCase() + s.substring(1).toLowerCase() I guess. Oh, since the question seems to indicate ES5, transformation is cheap although noticeably more verbose:

function capitalize (sentence) {
    return sentence.split(' ').map(
        function (s) {
            return s[0].toUpperCase() + s.substring(1).toLowerCase()      
        }).join(' ') ;
}

That is, assuming you'd want another sentence returned.

intboolstring
  • 6,891
  • 5
  • 30
  • 44
Rob Jens
  • 584
  • 6
  • 8
3

Here is a working piece of code. The problematic line in your code was this one:

newstr[i].charAt(0).toUpperCase();

That line gets the uppercased first letter of each word, but it doesn't do anything with it. The way the code below works is that it uppercases the first character, then appends the rest of the word, then assigns that back into newstr[i].

function titleCase(str) {
  var newstr = str.split(" ");
  for(i=0;i<newstr.length;i++){
    newstr[i] = newstr[i].charAt(0).toUpperCase() + newstr[i].substring(1).toLowerCase();
  }
   newstr = newstr.join(" ");
   return newstr;
}
Maximillian Laumeister
  • 19,884
  • 8
  • 59
  • 78
3

This should work. Notice how I set newstr[i] to the desired output. Functions like .toUpperCase() do not affect the original string. They only return a new string with the desired property.

function titleCase(str) {
  var newstr = str.split(" ");
  for(i=0;i<newstr.length;i++){
    if(newstr[i] == "") continue;
    var copy = newstr[i].substring(1).toLowerCase();
    newstr[i] = newstr[i][0].toUpperCase() + copy;
  }
   newstr = newstr.join(" ");
   return newstr;
}  
Devin Spikowski
  • 2,946
  • 2
  • 12
  • 13
JCOC611
  • 19,111
  • 14
  • 69
  • 90
  • I think your code is just fine but you are making a `copy` variable during each iteration. I would suggest that you declare your `copy` variable before loop and initialize it with new value in loop. – Muhammad Talha Akbar Jul 18 '15 at 20:30
  • 3
    @RexOverflow There is [actually no difference](https://stackoverflow.com/questions/3684923/javascript-variables-declare-outside-or-inside-loop) between declaring a variable in or outside a for loop, because variable declarations are evaluated at parse-time, and not run-time. – Maximillian Laumeister Jul 18 '15 at 20:33
  • @MaximillianLaumeister Thanks :D Helpful resource. – Muhammad Talha Akbar Jul 18 '15 at 20:34
3

If you enjoy using Ramda like I do, you can do this clean fun thing:

import { concat, compose, head, join, map, split, tail, toLower, toUpper } from 'ramda';    
const toWords = split(' ');
const capitalizeWords = map(s => concat(toUpper(head(s)), toLower(tail(s))));
const toSentence = join(' ');
const toTitleCase = compose(toSentence, capitalizeWords, toWords);

or of course you can always cut it down to

const capitalizeWords = map(s => concat(toUpper(head(s)), toLower(tail(s))));
const toTitleCase = compose(join(' '), capitalizeWords, split(' '));
  • if you have words not already separated by spaces, try adding a replace to the first (right most) operation in compose for replace. For example, I needed to first replace dashes with spaces before the split. replace(/-/g, ' ') – Brandon Culley Jun 21 '19 at 02:21
2
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}

This function uppercases 1st letter and lowercases the rest part od the string.

A bit changed function from the perfect answer found here: How do I make the first letter of a string uppercase in JavaScript?

Community
  • 1
  • 1
Reflective
  • 3,854
  • 1
  • 13
  • 25
1

I recently redid this problem using regex which matches the first letter and accounts for apostrophe. Hope it's helpful:

function titleCase(str) {

return str.toLowerCase().replace(/^\w|\s\w/g, function(firstLetter) {
    return firstLetter.toUpperCase();
  });
}
titleCase("I'm a little tea pot");
BillyD
  • 471
  • 4
  • 3
1

Here's a function titleCase(string, array) that transforms a string into title case, where the first letter of every word is capitalized except for certain prepositions, articles and conjunctions. If a word follows a colon, it will always be capitalized. You can include an optional array to ignore strings of your choice, such as acronyms.

I may have missed some exception words in the ignore array. Feel free to add them.

function titleCase(str, array){

  var arr = [];
  var ignore = ["a", "an", "and", "as", "at", "but", "by", "for", "from", "if", "in", "nor", "on", "of", "off", "or", "out", "over", "the", "to", "vs"];
  if (array) ignore = ignore.concat(array);
  ignore.forEach(function(d){
    ignore.push(sentenceCase(d));
  });

  var b = str.split(" ");

  return b.forEach(function(d, i){
    arr.push(ignore.indexOf(d) == -1 || b[i-1].endsWith(":") ? sentenceCase(d) : array.indexOf(d) != -1 ? d : d.toLowerCase());
  }), arr.join(" ");

  function sentenceCase(x){
    return x.toString().charAt(0).toUpperCase() + x.slice(x.length-(x.length-1));
  }

}

var x = titleCase("james comey to remain on as FBI director", ["FBI"]);
console.log(x); // James Comey to Remain on as FBI Director
var y = titleCase("maintaining substance data: an example");
console.log(y); // Maintaining Substance Data: An Example
Harry Stevens
  • 1,373
  • 1
  • 15
  • 18
1
const titleCase = str => {
    let string = str.toLowerCase().split(" ");
    let arr = [];
    
    string.map(x =>arr.push(x[0].toUpperCase() + x.slice(1))) 
    
    return arr.join(" ");
}
  • 4
    This would be a better answer if you explained how the code you provided answers the question. – pppery Aug 01 '20 at 20:51
0
function titleCase(str) {
    var titleStr = str.split(' ');

    for (var i = 0; i < titleStr.length; i++) {

        titleStr[i] = titleStr[i].charAt(0).toUpperCase() + titleStr[i].slice(1).toLowerCase();

    }

    return titleStr.join(' ');
}

titleCase("i'm a little tea pot")
Smittey
  • 2,475
  • 10
  • 28
  • 35
0

My Solution

function titleCase(str) {

var myArr = str.toLowerCase().split(" ");

for (var a = 0; a < myArr.length; a++){
     myArr[a] = myArr[a].charAt(0).toUpperCase() + myArr[a].substr(1);
  }

  return myArr.join(" ");
}
Gustoko
  • 11
0
function titleCase(str) {
  var newArr = str.toLowerCase().split(" "), 
  firstLetter, 
  updArr = [];
  for(var i=0;i<newArr.length;i+=1){
    firstLetter = newArr[i].slice(0,1);
    updArr.push(newArr[i].replace(firstLetter, firstLetter.toUpperCase()));
  }
  return updArr.join(" ");
}
Vishal
  • 404
  • 3
  • 9
0

First all become lowercase, and then open each word, and then open each letter, the first letter set capital, and then together

function titleCase(str) {
  var copy=str;
  copy=copy.toLowerCase();
  copy=copy.split(' ');
  for(var i=0;i<copy.length;i++){
    var cnt=copy[i].split('');
    cnt[0]=cnt[0].toUpperCase();
    copy[i]=cnt.join('');
    
    
  }
  str=copy.join(' ');
  return str;
}

titleCase("I'm a little tea pot");
0
let text_lower_case = text.toLowerCase();
let result = text_lower_case.replace(/(^\w{1}|\.\s*\w{1})/gi, function(toReplace){ return toReplace.toUpperCase(); });

First, you need to convert all the letters lowercase, and then replace all the first charters to uppercase before the period or dot.

Example: https://tunepit.net/tool/convert-case

Raza
  • 1
-1
function titleCase(str){
    var strToArray = str.split(" ");
    var newArray = [];       

    for(var i=0; i < strToArray.length; i++){
        var element = strToArray[i].replace(strToArray[i][0], strToArray[i][0].toUpperCase());
        newArray.push(element);
    }

    return (newArray.join(" "));
}
Remi Guan
  • 21,506
  • 17
  • 64
  • 87