最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Function to capitalize first and last letter of each word not working - Stack Overflow

programmeradmin1浏览0评论

I created a function that given any string will return the string with the first and last letter of each word capitalized. So far it works in some words, not on others, can someone help me figure out why?

function Capitalize(str) {
  var spl = str.split(" "); 
  var words = [];
  for (let i = 0; i < spl.length; i++) {
    //For every word
    for (let j = 0; j < spl[i].length; j++) {
      //For every letter in each word
      var word = spl[i];
      var size = spl[i].length;
      var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
      var LastLetterCapital = firstLetterCapital.replace(
        word[size - 1],
        word[size - 1].toUpperCase()
      );
    }
    words.push(LastLetterCapital);
  }
  console.log(words.join(" "));
}

Capitalize("hello there");

It works when I type : Capitalize("my name is john smith"), but not with Capitalize("hello there")

I know it's a plete mess and probably a very bad way to do it, but I started programming a month ago so give me a break :)

I created a function that given any string will return the string with the first and last letter of each word capitalized. So far it works in some words, not on others, can someone help me figure out why?

function Capitalize(str) {
  var spl = str.split(" "); 
  var words = [];
  for (let i = 0; i < spl.length; i++) {
    //For every word
    for (let j = 0; j < spl[i].length; j++) {
      //For every letter in each word
      var word = spl[i];
      var size = spl[i].length;
      var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
      var LastLetterCapital = firstLetterCapital.replace(
        word[size - 1],
        word[size - 1].toUpperCase()
      );
    }
    words.push(LastLetterCapital);
  }
  console.log(words.join(" "));
}

Capitalize("hello there");

It works when I type : Capitalize("my name is john smith"), but not with Capitalize("hello there")

I know it's a plete mess and probably a very bad way to do it, but I started programming a month ago so give me a break :)

Share Improve this question edited Dec 29, 2019 at 22:33 nibble 4044 silver badges15 bronze badges asked Dec 29, 2019 at 21:16 alokagobalokagob 735 bronze badges 7
  • Can you show your function? – Yousername Commented Dec 29, 2019 at 21:16
  • var LastLetterCapital = firstLetterCapital.replace( word[size - 1], word[size - 1].toUpperCase() ); makes no sense, what happens if the letter is somewhere else in the word? – epascarello Commented Dec 29, 2019 at 21:22
  • @epascarello Where else would the last letter in the word be? Caesar cipher, by George! – Dave Newton Commented Dec 29, 2019 at 21:23
  • What is the use of the j loop to iterate over characters when you need to work only on words? – Akshit Mehra Commented Dec 29, 2019 at 21:24
  • Ask yourself why you have an inner loop. You never actually use j. – trincot Commented Dec 29, 2019 at 21:24
 |  Show 2 more ments

9 Answers 9

Reset to default 1

@symlink has already explained why it is "HellO ThEre" instead of "Hello TherE". He also has given a solution to explicitly target first and last character of the string. I have acplished not much different than already posted by members, except for .. "may be" a little more explanation.

You can break the entire problem in these four steps.

  1. Get all the words into an array.
  2. Create a function, that takes each word and targets first and last character, changes it and returns the changed word.
  3. Apply a mapping step using the function created above (in step 2) to the entire array of words (obtained in step 1).
  4. Join the transformed array, obtained in step 3, using a blank space as a separator.

I have written two functions that acplish this task. I am sorry for long name of functions. It helps me keep track of things in a plex program (especially when I am in a hurry!).

Step 2 function

function Capitalize_FirstAndLast_One_Word(word){
// Split the string in array for easy access/manipulation by indexing
    Split_String = word.split("")
// Target the first word
    Split_String[0] = Split_String[0].toUpperCase();
// Target the last word
    Split_String[Split_String.length - 1] = Split_String[Split_String.length - 1].toUpperCase();
// Join the array into a single word
    Joined_Back = Split_String.join("")
    return Joined_Back;
}

Step 1, 3 and 4 function

function Capitalize_Entire_String(str){
 Regular_Exp = new RegExp(/\w+/g);  

//Below is step 1
 MatchedArray = str.match(Regular_Exp);

//Below is step 3
 ConvertedArray = MatchedArray.map(Capitalize_FirstAndLast_One_Word);

// Below is step 4
 ReturnedString = ConvertedArray.join(" ");
 console.log(ReturnedString);
 return ReturnedString;
}

Now you have everything. You can use the function like below.

Capitalize_Entire_String("hello there");
Capitalize_Entire_String("hello there this is a test");

Hope this helps. I am sorry if this turned out to be a redundant answer for you.

Reason your code don't work is the use of replace(). replace() will always replace the first character found.

There is absolutely no reason to run a nested loop. You can achieve this using a single loop.

function cap(str){
  let spl = str.split(' ');
  for(let i = 0; i < spl.length; i++){
    let temp = spl[i];
    temp = temp[0].toUpperCase() + temp.slice(1)
    temp = temp.slice(0,-1) + temp[temp.length - 1].toUpperCase();
    spl[i] = temp;
  }
  return spl.join(' ');
}

console.log(cap("a quick brown fox"))

An easier way is to use map() and template strings.

const cap = str => str
                     .split(' ')
                     .map(x => (
                         x.length === 1 ? 
                             x.toUpperCase() : 
                            `${x[0].toUpperCase()}${x.slice(1,-1)}${x[x.length -1].toUpperCase()}`)
                     )  
                     .join(' ')

console.log(cap("a quick brown fox"))

To simplify the function, you could split the string into an array, map each word to the desired format, and join it together into a string again.

function Capitalize(str){
	return str.split(" ").map((word) => word.charAt(0).toUpperCase() + 
		(word.length > 2 ? word.substring(1, word.length - 1) : "") + 
		(word.length > 1 ? word.charAt(word.length - 1).toUpperCase() : "")).join(" ");
}

console.log(Capitalize("i want to capitalize first and last letters"));

Congrats on starting out programming...

You can use this to achieve what you want to do

function capitalizeFirstAndLastLetters (str) {
    const words = str.split(" "); // Split the string into words
    const modified = [];

    for (const word of words) {
        if (word.length <= 2) {
            modified.push(word.toUpperCase()); // If the word less than 3 characters, the whole word is capitalized
            continue;
        }

        var firstCapital = word[0].toUpperCase(); // word[0] gets the first index of the string (I.e. the first letter of the word)
        var lastCapital = word.slice(-1).toUpperCase(); // The slice function slices a portion of the word. slice(-1) gets the last letter
        var middlePart = word.slice(1, -1); // slice(1, -1) means start slicing from the second index (I.e. 1) and ignore the last index

        modified.push(firstCapital + middlePart + lastCapital);
    }

    return modified.join(" "); // Join each element in the modified array with a space to get the final string with each words first and last letters capitalized
}

capitalizeFirstAndLastLetters("hello there I am a boy"); // "HellO TherE I AM A BoY"

Try this, it worked for hello world because I guess you want the oute to be HellO TherE right?:

  function capitalize(str) {
  var spl = str.split(" "); 
  var words = [];
  for (let i = 0; i < spl.length; i++) {
    //For every word

    let changedWord = "";
    for (let j = 0; j < spl[i].length; j++) {
      //For every letter in each word
      if(j == 0 || j == spl[i].length - 1) {
        changedWord += spl[i][j].toUpperCase();
      } else {
        changedWord += spl[i][j].toLowerCase();
      }

    }
    words.push(changedWord);
    console.log(words);
  }
  console.log(words.join(" "));
}

capitalize("hello there");

ALSO: Make your functions name start with lowercase letter. Thats just how it is. Starting with uppercase letters usually are Classes. Just a quick tip

Maybe this does what you want, don't want to change much from your code:

function Capitalize(str) {
  var spl = str.split(" "); 
  var words = [];
  for (let i = 0; i < spl.length; i++) {
    
    var word = spl[i];
    
    var firstCapital = word[0].toUpperCase(); // get first character after capitalizing
    var lastCapital = word.slice(-1).toUpperCase(); // get last character after capitalizing
    var midOriginal = word.slice(1, -1);
    
    words.push(firstCapital + midOriginal + lastCapital) // concat 3 parts
    
  }
  console.log(words.join(" "));
}

Capitalize("hello there");

This expression:

var LastLetterCapital = firstLetterCapital.replace(
    word[size - 1],
    word[size - 1].toUpperCase()
  );

Is replacing the first occurrence of the character "e" in "There" with an uppercase "E".

Explanation

The replace() function first translates the first param: word[size - 1] to the literal character "e", then replaces the first occurrence of that character with the uppercase "E", resulting in the string "ThEre".

Solution

Use a regular expression as your first parameter instead, to ensure that the last character is targeted, regardless of whether or not that same character shows up anywhere else in the word:

  var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());

function Capitalize(str) {
  var spl = str.split(" "); 
  var words = [];
  for (let i = 0; i < spl.length; i++) {
    //For every word
    var word = spl[i];
    var size = spl[i].length;
    for (let j = 0; j < size; j++) {
      //For every letter in each word      
      var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
      var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
    }
    words.push(LastLetterCapital);
  }
  console.log(words.join(" "));
}

Capitalize("hello there");

This should do the trick:

function Capitalize(str) {
  return str.replace(/(\b\w|\w\b)/g, l => l.toUpperCase())
}

console.log(Capitalize('i want to be capitalized in a rather strange way'))

Explanation:

In the regular expression /(\b\w|\w\b)/g, \b means "word boundary" and \w means "word character", so (\b\w|\w\b) matches a word boundary followed by a word character OR a word character followed by a word boundary (i.e. the first and last character of words).

The matches of this expression are then passed to the inline function l => l.toUpperCase() (which itself is the second argument to replace) that capitalizes the passed letter.

the string type is immutable, so why don't you try to convert the string to an array like y = word.split('') and do y[0] = word.charAt(0).toUpperCase() and then convert back to string with y.join('')

发布评论

评论列表(0)

  1. 暂无评论