标题大写一句话——哪种解决方案更好,为什么?

Title case a sentence - Which solution is better and why?

我是编程新手。我用两种不同的方式编写了一个解决方案,但想知道什么被认为是更好的解决方案,以及为什么。

此外,在性能方面,为什么会被认为更好?

解决方案 1:

function titleCase(str) {
  str = str.toLowerCase();
  str = str.split("");
  str[0] = str[0].toUpperCase();
  for(i = 1; i<str.length; i++){
    if(str[i+1] == " "){
      str[i+2] = str[i+2].toUpperCase();
    }
  }
  str = str.join("");
  return str;
}

解决方案 2:

function titleCase(str) {
  str = str.toLowerCase();
  str = str.split(" ");
  str = str.map(function(val){
    val = val.charAt(0).toUpperCase() + val.slice(1);
    return val;
  });
  str = str.join(" ");
  return str;
}

哪种解决方案最好?

你的第二个解决方案是最好的,但通过链接 str 上的方法调用并删除 map 中不必要的 val 重新分配可能会更好:

function titleCase(str) {
  return str
      .toLowerCase()
      .split(" ")
      .map(function (val) {
          return val.charAt(0).toUpperCase() + val.slice(1);
      })
      .join(" ");
}

或者使用 ES6,我们可以使用 arrow function:

减小 map 块的大小
function titleCase(str) {
  return str
      .toLowerCase()
      .split(" ")
      .map((val) => val.charAt(0).toUpperCase() + val.slice(1))
      .join(" ");
}

我想说第二种解决方案最好的最明显原因是它更容易理解。通过使用像 map 这样的命名方法,从一开始就很清楚正在执行哪种操作。看一个 for 循环并不清楚你在映射值。

______

哪个最适合性能?

我建议您使用大型数据集对每个进行测试。我怀疑您会发现每种方法之间实际上差别很小,并且由于需要较少的函数调用,第一种方法的执行时间可以忽略不计。

第二个要好得多,因为它可以立即清楚发生了什么,而无需弄清楚循环结构有哪些副作用。也可以说它更 functional.

也可以简化为一个简单的链,没有那么多变量赋值,这样更容易理解:

function titleCase(str) {
  return str.toLowerCase()
  .split(" ")
  .map(function(val) {
    return val.charAt(0).toUpperCase() + val.slice(1);
  })
  .join(" ");
}

第一个比较复杂的循环结构也是两个bug的原因:

  • 它不会以 space
  • 开头的字符串首字母大写
  • 它抛出以 space1
  • 结尾的字符串

当从 1 循环到 length-1 时,您应该使用 str[i-1] == " "str[i] = …

另请注意,通常认为将两种不同类型分配给同一变量是一种不好的做法。当处理一个字符串和一个字符数组时,你应该为它们使用两个不同的变量,而不是为两者使用 str

1:诚然,如果您使用 val[0].toUpperCase() 而不是 .charAt(0)(产生空字符串而不是 undefined,您的第二个函数也会发生同样的情况对于超出范围的索引)

我喜欢我的外观,因为它更易于阅读,它使用 lambda 函数,我有一个厚颜无耻的字符串数组访问,仅此而已:

function titleCase(str) {
  return str
    .toLowerCase()
    .split(" ")
    .map(word => word[0].toUpperCase() + word.slice(1))
    .join(" ")
}

当然,单词边界是个问题。