无法更新字符串的第一个字符 - Javascript

Can not update first character of a string - Javascript

我有以下代码应该将每个单词的第一个字母大写。但是第一个字符 arr[i][0] 没有得到更新。我最终做了 arr[i] = arr[i][0].toUpperCase() + arr[i].substr(1) 这有效但我不明白为什么下面不起作用。

function titleCase(string) {
  const arr = string.split(' ');
  for (let i = 0; i < arr.length; i++){
    arr[i][0] = arr[i][0].toUpperCase();
  }
  return arr.join(' ');
}

因为字符串在 JavaScript 中是不可变的,这意味着您无法更改它们。每次您尝试修改字符串时,实际上都是在创建一个包含更改的新字符串。

所以当您执行 arr[i][0] 时,它不是对第一个字符的引用,而是对第一个字符副本的引用。由于您没有保留该引用(即通过将其分配给变量),因此它丢失了。

您修复它的方法 arr[i] = arr[i][0].toUpperCase() + arr[i].substr(1) 是一种很好的方法。

正如其他人指出的那样,字符串在 JavaScript 中是 不可变的 ,这意味着您无法更改它们的值。如果你想让字符串的第一个字母大写,你必须构造一个 new string

str[0].toUpperCase() + str.slice(1)

或者更一般地说,如果我们在特定索引处使用大写字母,i

str.slice(0,i) + str[i].toUpperCase() + str.slice(i + 1)

我们可以创建一个函数toUpperCaseAt,它接受一个字符串和一个索引并为我们执行这个操作。

const toUpperCaseAt = (str = "", i = 0) =>
  i >= str.length
    ? str
    : str.slice (0, i) + str [i] .toUpperCase () + str.slice (i + 1)

接下来,我们编写一个简单的递归函数 titleCase 遍历字符串,一次一个字母。

  • 基本情况:索引越界 – return 输入字符串
  • 归纳案例 1:索引未越界且索引为 0 – 首字母应始终大写
  • 归纳案例2:索引不越界,不为0,索引当前引用了一个space字符——大写下一个字母
  • 归纳案例3:索引不越界,不为0,不为space——前进到下一个索引

此答案不需要依赖高级内置函数,如 String.prototype.splitArray.prototype.join – 相反,它向您展示了如何使用您自己创建的简单函数来实现结果。

const titleCase = (str = "", i = 0) =>
  i >= str.length
    ? str
    : i === 0
      ? titleCase (toUpperCaseAt (str, i), 1)
      : str [i] === " "
        ? titleCase (toUpperCaseAt (str, i + 1), i + 1)
        : titleCase (str, i + 1)

console.log (titleCase ('hello, my name is me.'))
// Hello, My Name Is Me.

如果我们不确定它是如何工作的,我们甚至可以删除 String.prototype.slice 依赖项

const slice = (str = "", from = 0, to = str.length) =>
  from >= to
    ? ''
    : str [from] + slice (str, from + 1, to)

现在一切都在一起了

const slice = (str = "", from = 0, to = str.length) =>
  from >= to
    ? ""
    : str [from] + slice (str, from + 1, to)

const toUpperCaseAt = (str = "", i = 0) =>
  i >= str.length
    ? str
    : slice (str, 0, i) + str [i] .toUpperCase () + slice (str, i + 1)

const titleCase = (str = "", i = 0) =>
  i >= str.length
    ? str
    : i === 0
      ? titleCase (toUpperCaseAt (str, i), 1)
      : str [i] === " "
        ? titleCase (toUpperCaseAt (str, i + 1), i + 1)
        : titleCase (str, i + 1)
        
console.log (titleCase ('hello, my name is me.'))
// Hello, My Name Is Me.

function titleCase(string) {
  const arr = string.split(' ');

  for (let i = 0; i < arr.length; i++) {
  
    // arr[i] is a String!!!
    const word = arr[i];
    
    // now, in order to target and mutate the [0]th key we need an Array:
    let charsArray = word.split("");
    
    // Now you can do .toUpperCase() on the [0]th array key
    charsArray[0] = charsArray[0].toUpperCase();
    
    // Convert Array to string and update arr[i]
    arr[i] = charsArray.join("");

  }
  return arr.join(' ');
}

console.log( titleCase("hello world") )

或者你可以simply use String.prototype.replace()MDN

const titleCase = str => str.replace(/\b(\w)/g, f => f.toUpperCase());

console.log( titleCase("hello world") )