簡體   English   中英

每個單詞的首字母大寫

[英]Capitalize the first letter of each word

var name = "AlbERt EINstEiN";

function nameChanger(oldName) {
var finalName = oldName;
// Your code goes here!
finalName = oldName.toLowerCase();

finalName = finalName.replace(finalName.charAt(0), finalName.charAt(0).toUpperCase());

for(i = 0; i < finalName.length; i++) {
    if (finalName.charAt(i) === " ")
        finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
}


// Don't delete this line!
return finalName;
};

// Did your code work? The line below will tell you!
console.log(nameChanger(name));

我的代碼原樣返回'Albert einstein'。 我想知道我哪里出錯了? 如果我添加

console.log(finalName.charAt(i+1));

在if語句之后,並注釋掉其余的語句,它打印出'e',因此它會像應該的那樣識別charAt(i+1) ...我只是無法用它大寫第二個單詞的第一個字母。

您的代碼示例有兩個問題。 我將一一介紹。

字符串是不可變的

這不符合您的想法:

finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());

您需要將其更改為:

finalName = finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());

在JavaScript中,字符串是不可變的 這意味着一旦創建了字符串,就無法更改它。 這聽起來可能很奇怪,因為在您的代碼中,似乎您正在使用replace()類的方法在整個循環中更改字符串finalName

但是實際上,您實際上並沒有改變它! replace()函數接受輸入字符串,進行替換,並產生新的輸出字符串 ,因為實際上不允許更改輸入字符串(不變性)。 因此,tl; dr,如果不通過將replace()的輸出分配給變量來捕獲它,則替換的字符串將丟失。

順便說一句,可以將其分配回原始變量名稱,這就是為什么可以執行finalName = finalName.replace(...)


替換貪婪

您遇到的另一個問題是,當您使用replace() ,您將替換字符串中所有匹配的字符,而不僅僅是替換您正在檢查的位置的字符。 這是因為replace()是貪婪的-如果您告訴它用'E'替換'e',它將全部替換!

本質上,您需要做的是:

  1. 查找一個空格字符(您已經完成了此操作)
  2. 抓住所有弦,直到並包括空格; 字符串的這個“邊”是好的。
  3. 將下一個字母轉換為大寫字母,但僅轉換為大寫字母。
  4. 抓住剩下的字符串, 經過轉換后的字母。
  5. 將所有三個部分放在一起(字符串的開頭,大寫字母,字符串的結尾)。

slice()方法將執行您想要的操作:

if (finalName.charAt(i) === " ") {
    // Get ONLY the letter after the space
    var startLetter = finalName.slice(i+1, i+2);
    // Concatenate the string up to the letter + the letter uppercased + the rest of the string
    finalName = finalName.slice(0, i+1) + startLetter.toUpperCase() + finalName.slice(i+2);
}

另一個選擇是正則表達式(regex),其他答案也提到了正則表達式。 這可能是一個更好的選擇,因為它要干凈得多。 但是,如果您是第一次學習編程,則可以通過編寫原始循環來更輕松地理解此手動字符串工作。 稍后,您可以搞清楚有效的方法。

工作jsfiddle: http : //jsfiddle.net/9dLw1Lfx/

進一步閱讀:

如果將RegExp /pattern/flags和一個函數傳遞給str.replace而不是使用子字符串,則可以將其簡化很多

function nameChanger(oldName) {
    var lowerCase = oldName.toLowerCase(),
        titleCase = lowerCase.replace(/\b./g, function ($0) {return $0.toUpperCase()});
    return titleCase;
};

在本例中,我將更改應用於任何字符. 單詞邊界\\b ,但您可能需要更具體的/(^| )./g

這個問題的另一個很好的答案是使用RegEx為您執行此操作。

var re = /(\b[a-z](?!\s))/g;
var s = "fort collins, croton-on-hudson, harper's ferry, coeur d'alene, o'fallon"; 
s = s.replace(re, function(x){return x.toUpperCase();});
console.log(s); // "Fort Collins, Croton-On-Hudson, Harper's Ferry, Coeur D'Alene, O'Fallon"

使用的正則表達式可能需要稍作更改,但這應該使您了解如何使用正則表達式

用JavaScript大寫字母

問題是雙重的:

1)您需要為finalName.replace返回一個值,因為該方法會返回一個元素,但不會更改該元素所基於的元素。

2)您不需要遍歷字符串值,因此只更改了第一個單詞。 您是否不想更改每個單詞,使其大寫小寫?

此代碼將為您提供更好的服務:

   var name = "AlbERt EINstEiN";

function nameChanger(oldName) {

    // Your code goes here!

    var finalName = [];
    oldName.toLowerCase().split(" ").forEach(function(word) {
        newWord = word.replace(word.charAt(0), word.charAt(0).toUpperCase());
        finalName.push(newWord);
    });


    // Don't delete this line!
    return finalName.join(" ");
};

    // Did your code work? The line below will tell you!
    console.log(nameChanger(name));
if (finalName.charAt(i) === " ")

不是嗎

if (finalName.charAt(i) == " ")

不===檢查對象類型是否相等,這不應該是一個字符,而另一個是字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM