Artigo original: Three Ways to Title Case a Sentence in JavaScript

Este artigo se baseia no script de algoritmos básicos do Free Code Camp chamado "Capitalizar a primeira letra de cada palavra de uma frase".

Nesse algoritmo, queremos mudar uma string (texto) para que tenha sempre uma letra maiúscula no início de cada palavra.

Neste artigo, vou explicar três abordagens: a primeira com um laço for, a segunda usando o método map() e a terceira usando o método replace().

Desafio do algoritmo

Retorne a string fornecida com a primeira letra de cada palavra em letra maiúscula. Certifique-se de que o resto da palavra esteja em letras minúsculas.

Para o propósito desse exercício, você também deve capitalizar as palavras conectoras como the e of.

Casos de teste fornecido

  • titleCase("I’m a little tea pot") deve retornar uma string.
  • titleCase("I’m a little tea pot") deve retornar "I'm A Little Tea Pot".
  • titleCase("sHoRt AnD sToUt") deve retornar "Short And Stout".
  • titleCase("HERE IS MY HANDLE HERE IS MY SPOUT") deve retornar "Here Is My Handle Here Is My Spout".

1. Capitalize cada palavra de uma frase com um laço FOR

Para esta solução, usaremos o método String.prototype.toLowerCase(), o método String.prototype.split(), o método String.prototype.charAt(), o método String.prototype.slice() e o método Array.prototype.join().

  • O método toLowerCase() retornará o valor da string que o chama convertido em letras minúsculas.
  • O método split() divide um objeto de string em um array de strings separando a string em substrings.
  • O método charAt() retorna o caractere especificado de uma string.
  • O método slice() extrai uma parte de uma string e a retorna como uma nova string.
  • O método join() reúne todos os elementos do array em uma string.

Nós vamos precisar acrescentar um espaço vazio entre os parênteses do método split(),

var strSplit = "I'm a little tea pot".split(' ');

que produzirá um conjunto de palavras separadas:

var strSplit = ["I'm", "a", "little", "tea", "pot"];

Se você não adicionar o espaço entre parênteses, você terá este resultado:

var strSplit = ["I", "'", "m", " ", "a", " ", "l", "i", "t", "t", "l", "e", " ", "t", "e", "a", " ", "p", "o", "t"];

Então, vamos concatenar

str[i].charAt(0).toUpperCase()

— que transformará em maiúsculo o caractere de índice 0 (zero) da string atual no laço FOR —

e

str[i].slice(1)

— que extrairá os caracteres do índice 1 até o final da string.

Vamos colocar toda a string em letras minúsculas para fins de normalização.

Com comentários:


function titleCase(str) {
  // Passo 1. Converta a string em minúsculas
  str = str.toLowerCase();
  // str = "I'm a little tea pot".toLowerCase();
  // str = "i'm a little tea pot";
  
  // Passo 2. Divida a string em um array de strings
  str = str.split(' ');
  // str = "i'm a little tea pot".split(' ');
  // str = ["i'm", "a", "little", "tea", "pot"];
  
  // Passo 3. Crie o laço FOR
  for (var i = 0; i < str.length; i++) {
    str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1); 
  /* Aqui str.length = 5
      1ª iteração: str[0] = str[0].charAt(0).toUpperCase() + str[0].slice(1);
                   str[0] = "i'm".charAt(0).toUpperCase()  + "i'm".slice(1);
                   str[0] = "I"                            + "'m";
                   str[0] = "I'm";
      2ª iteração: str[1] = str[1].charAt(0).toUpperCase() + str[1].slice(1);
                   str[1] = "a".charAt(0).toUpperCase()    + "a".slice(1);
                   str[1] = "A"                            + "";
                   str[1] = "A";
      3ª iteração: str[2] = str[2].charAt(0).toUpperCase()   + str[2].slice(1);
                   str[2] = "little".charAt(0).toUpperCase() +"little".slice(1);
                   str[2] = "L"                              + "ittle";
                   str[2] = "Little";
      4ª iteração: str[3] = str[3].charAt(0).toUpperCase() + str[3].slice(1);
                   str[3] = "tea".charAt(0).toUpperCase()  + "tea".slice(1);
                   str[3] = "T"                            + "ea";
                   str[3] = "Tea";
      5ª iteração: str[4] = str[4].charAt(0).toUpperCase() + str[4].slice(1);
                   str[4] = "pot".charAt(0).toUpperCase() + "pot".slice(1);
                   str[4] = "P"                           + "ot";
                   str[4] = "Pot";                                                         
    Fim do laço FOR */
  }
  
  // Passo 4. Retorne o resultado
  return str.join(' '); // ["I'm", "A", "Little", "Tea", "Pot"].join(' ') => "I'm A Little Tea Pot"
}

titleCase("I'm a little tea pot");

Sem comentários:

function titleCase(str) {
  str = str.toLowerCase().split(' ');
  for (var i = 0; i < str.length; i++) {
    str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1); 
  }
  return str.join(' ');
}
titleCase("I'm a little tea pot");

2. Capitalize cada palavra de uma frase com o método map()

Nesta solução, usaremos o método Array.prototype.map().

  • O método map() cria um array com os resultados de chamar uma função dada em cada elemento desse array. Ao usar map, chamamos uma função de callback fornecida uma vez para cada elemento do array, em sequência, e criamos outro array a partir dos resultados.

Vamos colocar as letras em minúsculas e dividir a string, como visto no exemplo anterior antes de aplicar o método map().

Ao invés de usar um laço FOR, aplicaremos o método map() como condição na mesma concatenação do exemplo anterior.

(word.charAt(0).toUpperCase() + word.slice(1));

Com comentários:


function titleCase(str) {
  // Passo 1. Converta a string em minúsculas
  str = str.toLowerCase() // str = "i'm a little tea pot";
  
  // Passo 2. Divida a string em um array de strings
           .split(' ') // str = ["i'm", "a", "little", "tea", "pot"];
         
  // Passo 3. Itere o array usando o Map
           .map(function(word) {
    return (word.charAt(0).toUpperCase() + word.slice(1));
    /* Processo do Map
    1ª palavra: "i'm"    => (word.charAt(0).toUpperCase() + word.slice(1));
                          "i'm".charAt(0).toUpperCase()   + "i'm".slice(1);
                                "I"                       +     "'m";
                          return "I'm";
    2ª palavra: "a"      => (word.charAt(0).toUpperCase() + word.slice(1));
                          "a".charAt(0).toUpperCase()     + "".slice(1);
                                "A"                       +     "";
                          return "A";
    3ª palavra: "little" => (word.charAt(0).toUpperCase()  + word.slice(1));
                          "little".charAt(0).toUpperCase() + "little".slice(1);
                                "L"                        +     "ittle";
                          return "Little";
    4ª palavra: "tea"    => (word.charAt(0).toUpperCase() + word.slice(1));
                          "tea".charAt(0).toUpperCase()   + "tea".slice(1);
                                "T"                       +     "ea";
                          return "Tea";
    5ª palavra: "pot"    => (word.charAt(0).toUpperCase() + word.slice(1));
                          "pot".charAt(0).toUpperCase()   + "pot".slice(1);
                                "P"                       +     "ot";
                          return "Pot";                                                        
    Fim do método map() */
});

 // Passo 4. Retorne o resultado
 return str.join(' '); // ["I'm", "A", "Little", "Tea", "Pot"].join(' ') => "I'm A Little Tea Pot"
}

titleCase("I'm a little tea pot");

Sem comentários:

function titleCase(str) {
  return str.toLowerCase().split(' ').map(function(word) {
    return (word.charAt(0).toUpperCase() + word.slice(1));
  }).join(' ');
}
titleCase("I'm a little tea pot");

3. Capitalize cada palavra de uma frase com os métodos map() e replace()

Para esta solução, continuaremos usando o método Array.prototype.map() e adicionaremos o método String.prototype.replace().

  • O método replace() retorna uma nova string com algumas ou todas as correspondências de um padrão (em inglês, pattern) substituídas por aquilo que sugerirmos.

No nosso caso, o padrão (do inglês, pattern) para o método replace() será uma string que vai ser substituída (pelo segundo argumento do método) e que será tratada como uma string literal. Também podemos usar uma expressão regular como padrão para resolver esse algoritmo.

Vamos colocar as letras em minúsculas e dividir a string como visto no primeiro exemplo antes de aplicar o método map().

Com comentários:


function titleCase(str) {
  // Passo 1. Converta a string em minúsculas
  str = str.toLowerCase() // str = "i'm a little tea pot";
  
  // Passo 2. Divida a string em um array de strings
           .split(' ') // str = ["i'm", "a", "little", "tea", "pot"];
         
  // Passo 3. Itere o array usando o Map
           .map(function(word) {
    return word.replace(word[0], word[0].toUpperCase());
    /* Processo Map
    1ª palavra: "i'm" => word.replace(word[0], word[0].toUpperCase());
                       "i'm".replace("i", "I");
                       return word => "I'm"
    2ª palavra: "a" => word.replace(word[0], word[0].toUpperCase());
                     "a".replace("a", "A");
                      return word => "A"
    3ª palavra: "little" => word.replace(word[0], word[0].toUpperCase());
                          "little".replace("l", "L");
                          return word => "Little"
    4ª palavra: "tea" => word.replace(word[0], word[0].toUpperCase());
                       "tea".replace("t", "T");
                       return word => "Tea"
    5ª palavra: "pot" => word.replace(word[0], word[0].toUpperCase());
                       "pot".replace("p", "P");
                       return word => "Pot"                                                        
    Fim do método map() */
});

 // Passo 4. Retorne o resultado
 return str.join(' '); // ["I'm", "A", "Little", "Tea", "Pot"].join(' ') => "I'm A Little Tea Pot"
}

titleCase("I'm a little tea pot");

Sem comentários:

function titleCase(str) {
  return str.toLowerCase().split(' ').map(function(word) {
    return word.replace(word[0], word[0].toUpperCase());
  }).join(' ');
}
titleCase("I'm a little tea pot");

Espero que tenha achado este artigo útil. Ele é parte da minha série de artigos "Como resolver os algoritmos do freeCodeCamp", que trata dos desafios de algoritmos básicos em JavaScript do freeCodeCamp. Nessa série, proponho várias soluções passo a passo mostrando o que acontece internamente em cada um dos algoritmos dos desafios.

Três maneiras de repetir uma string em JavaScript
Neste artigo, eu explico como resolver o desafio "Repetir uma string Repetir uma string", do freeCodeCamp. (texto em inglês)

Duas maneiras de confirmar o final de uma string em JavaScript
Neste artigo, eu explico como resolver o desafio "Confirmar o final", do freeCodeCamp. (texto em inglês)

Três maneiras de encontrar o maior número em um array usando JavaScript
Neste artigo, eu explico como resolver o desafio "Retornar os maiores números em arrays" do freeCodeCamp. (texto em inglês)

Três maneiras de inverter uma string em JavaScript
Este artigo tem por base o desafio de criação de scripts de algoritmos básicos "Inverter uma string", do freeCodeCamp.

Três maneiras de encontrar o fatorial de um número em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Encontrar o fatorial de um número", do freeCodeCamp.

Duas maneiras de conferir palíndromos em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Verificador de palíndromo", do freeCodeCamp.

Três maneiras de encontrar a maior palavra em uma string em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Encontrar a palavra mais longa em uma string", do freeCodeCamp.

Se você tiver sua própria solução ou se tiver sugestões, compartilhe-as.

Você também pode seguir a autora no Medium, no Twitter, no Github e no LinkedIn ;-)

‪#‎SigaCurioso‬, ‪#SigaProgramando e ‪#‎FaçaAcontecer!

Recursos utilizados