问题描述
我正在尝试反转给定字符串中字符数为 5 或更多的所有单词。
这是我的代码:
function spinWords(string){
let stringArray = string.split(' ');
for (var i = 0; i < stringArray.length; i++) {
if ( stringArray[i].length >= 5) {
stringArray[i].split('').reverse().join('');
}
}
return stringArray.join(' ');
}
出于某种原因,我得到了相同的结果。我很感激一些帮助。
例如; 输入:“我每天都在学习编码” 输出:“我是 gninrael gnidoc yadyreve”
解决方法
行 stringArray[i].split('').reverse().join('')
不会原地反转,而是返回一个文本被反转的新字符串。这意味着数组本身保持不变。您需要使用反转单词覆盖位置 i 处的条目以实际反转单词。以下是更新后的示例。
function spinWords(string){
let stringArray = string.split(' ');
for (var i = 0; i < stringArray.length; i++) {
if ( stringArray[i].length >= 5) {
stringArray[i] = stringArray[i].split('').reverse().join('');
}
}
return stringArray.join(' ');
}
console.log(spinWords("this is a looooong word"))
虽然 Masheer Ali 提供了一个简单的单线,但我认为至少考虑如何将这些要求分解为更简单的部分总是值得的。您可能并不总是使用这样的细分。如果组件本身似乎没有用,最好将它们内联到主函数中。但通常它会使您的代码更简单、更易于理解,因此值得这样做。
这里是这样的细分:
const spin = (str) =>
str .split ('') .reverse () .join ('')
const spinLong = (n) => (str) =>
str .length > n ? spin (str) : str
const spinWords = (str) =>
str .split (' ') .map (spinLong (5)) .join (' ')
console .log (
spinWords ('Im learning coding everyday')
)
我们有三个功能。
-
spin
反转单个字符串。它对句子或“大于长度 5”的限制一无所知。它只是将'abc x yz'
之类的东西变成'zy x cba'
。 -
spinLong
仅反转长字符串,其中长度作为参数提供。这就是它所做的一切。它不知道如何翻转字符串本身,将实际的旋转委托给函数spin
。因此,它所要做的就是确定您的字符串是否足够长,如果足够则调用spin
。 -
spinWords
解决了提出的问题。它旋转句子中长度超过 5 个字母的所有单词。但它也不知道如何旋转单词,也不知道如何检查单词长度。它将该行为委托给spinLong
。在内部,它将句子拆分为单词,对每个单词调用spinLong (5)
,然后将它们组合成一个句子。
我们可以使用类似于 MasheerAli 的第二个版本的代码来内联它,如下所示:
const spinWords = (str) => str
.split (' ') .map ((s) => s .length > 5 ? s .split ('') .reverse () .join ('') : s) .join (' ')
这对我来说现在看起来不那么引人注目了。无论我们选择如何布局,它看起来更像是一堆步骤,而不是对我们想要完成的事情的描述。我觉得前面的更容易理解。
当然,您几乎总是可以使用这种风格走得更远。我们可以定义一个 makeWords
函数在空格上进行分割,以及一个 makeSentence
函数将这些空格放回单词之间。这是一个有趣的电话。我不认为这些特别引人注目,但可能值得研究,尤其是我们如何将它们粘合在一起。
好的,既然您在交付此关键业务功能方面做得非常好,您的老板告诉您有一个重要的新需求。对于某些客户,我们只会旋转超过 7 个字符的单词。对于另一个,它是 12。
而且你需要赶紧把它送到门外。 “一个小时后我需要这个。你多久能完成?” (来自一位老老板的真实引述,对于我不久后离开的职位。一个小时实际上是“下周二”,但重点是一样的。老板似乎认为代码时间表可以简单地由法令创建。) 大问题整个系统的调用现在取决于您漂亮的 spinWords
模块。你没有时间去改变他们所有的电话。但是您知道剪切和粘贴是一个坏主意。您需要在根上修复此问题。
好吧,您可以轻松地做到这一点,无需到处复制和粘贴。我们只需要一个带有附加参数的新函数,并重构 spinWords
来使用它:
const spinLongWords = (n) => (str) =>
str .split (' ') .map (spinLong (n)) .join (' ')
const spinWords = spinLongWords (5)
console .log (
spinWords ('Im learning coding everyday'),//~> Im gninrael gnidoc yadyreve
spinLongWords (7) ('Im learning coding everyday'),//~> Im gninrael coding yadyreve
spinLongWords (12) ('Im learning coding everyday') //~> Im learning coding everyday
)
“好的,老板。大功告成。我们可以在这场旋转危机结束后决定是保留旧的 spinWords
函数,该函数只处理 5 个以上字母的单词作为整个系统的默认情况还是重构一切都可以用直接调用我们新奇的 spinLongWords
函数来代替它们。它的优先级相当低,但在我们做出决定并实施之前,它应该被列为我们的技术债务。”
在 javascript 中,如果您在字符串上调用任何方法,它不会改变它,而是返回一个新值。您需要将该值存储在变量中并使用它。
function spinWords(string){
let stringArray = string.split(' ');
for (var i = 0; i < stringArray.length; i++) {
if ( stringArray[i].length >= 5) {
stringArray[i] = stringArray[i].split('').reverse().join('');
}
}
return stringArray.join(' ');
}
console.log(spinWords("Im learning coding everyday"));
使用 map()
和 filter()
const spinWords = string => string
.split(' ')
.map(x => x.length >= 5 ? x.split('').reverse().join('') : x )
.join(' ');
console.log(spinWords("Im learning coding everyday"));