标题大写一句话——哪种解决方案更好,为什么?
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(" ")
}
当然,单词边界是个问题。
我是编程新手。我用两种不同的方式编写了一个解决方案,但想知道什么被认为是更好的解决方案,以及为什么。
此外,在性能方面,为什么会被认为更好?
解决方案 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(" ")
}
当然,单词边界是个问题。