编写一个函数,该函数接受一个或多个单词的字符串,并返回相同的字符串,但五个或多个字母单词全部颠倒。传入的字符串将仅包含字母和空格。仅当存在多个单词时才包含空格。
我编写的代码将整个字符串反向。我相信它与if语句有关,它不能捕获大于5的单词。编写代码时,我的想法是首先将字符串转换为单词数组,使用for循环遍历数组并查找单词大于5,然后反转大于5的字词。我发现了类似的问题,这就是我寻求帮助的程度。我被困住了,任何帮助将不胜感激!我是编码和学习Java语言的新手。
function spinWords(backward){
var sentence = "";
var separate = backward.split("");
for (var i = separate.length - 1; i >= 0; i--){
if (separate[i].length >= 1){
sentence += separate[i].split("").reverse().join("");
}
else {
sentence += "" + separate[i];
}
}
return sentence;
}
spinWords("Hey fellow warriors");
答案 0 :(得分:3)
如果您使用正则表达式连续匹配5个或更多单词字符,并使用替换函数reverse
来查找它们,则逻辑可能会容易得多:
function spinWords(backward) {
return backward.replace(/\w{5,}/g, word => word.split('').reverse().join(''));
}
console.log(spinWords("Hey fellow warriors"));
要修复代码,您应该用空格(而不是空字符串)分隔输入字符串(名为backward
的可变字符串),以获取单词数组,然后进行迭代通过该数组(从头开始,而不是从结尾开始),检查每个单词的length
并与sentence
串联:
function spinWords(backward) {
var sentence = "";
var separate = backward.split(" ");
for (var i = 0; i < separate.length; i++) {
if (sentence) sentence += ' ';
if (separate[i].length >= 5) {
sentence += separate[i].split("").reverse().join("");
} else {
sentence += separate[i];
}
}
return sentence;
}
console.log(spinWords("Hey fellow warriors"));
答案 1 :(得分:0)
下面是有关解决此问题的可能方法的讨论。对于这样一个简单的问题,我可能不会做,但它显示出一种心态,可以使您更轻松地解决许多问题,并在重做时重用您的工作。
您想在这里做几件事,这样可能有助于将问题分解为若干步骤。
从根本上讲,您想反转某些单词。那么为什么不编写一个函数来做到这一点呢?应该很简单。这是一个版本:
const reverseWord = word => word.split('').reverse().join('')
reverseWord('word') //=> 'drow'
但是您只想对长度至少为5的单词执行此操作。无需重写现有功能,我们可以使用它来编写更复杂的功能:
const reverseIfGte5 = word => word.length >= 5 ? reverseWord(word) : word
reverseIfGte5('word') //=> 'word'
reverseIfGte5('supercalifragilisticexpialidocious')
//=> 'suoicodilaipxecitsiligarfilacrepus')
请注意,在这里,我们使用{em> reverseIfGte5
来写reverseWord
。因此,如果选择的话,我们的reverseWord
函数也可以被重用,而且每个函数都在做简单的事情。
我们现在可以通过
根据此功能编写spinWord
const spinWords = sentence => sentence.split(/\s+/).map(reverseIfGte5).join(' ')
spinWords('Hey fellow warriors') //=> 'Hey wollef sroirraw'
这符合预期。这可能是个好地方。但是...
我们上面的spinWords
函数负责两件事:
理想情况下,函数应仅对一件事情负责。 (当然,在确定如何分解此类责任时需要做出一些判断。)
将其分开可能会很有用。我们可以用不同的方式做到这一点。这是一个简单的例子:
const updateWords = wordFn => sentence => sentence.split(/\s+/).map(wordFn).join(' ')
const spinWords = updateWords(reverseIfGte5)
现在我们有了一个可重用的函数,例如,可以将其与一个明显的capitalizeFirstLetter
函数一起使用,例如:
const titleCase = updateWords(capitalizeFirstLetter)
titleCase('Hey fellow warriors') //=> 'Hey Fellow Warriors')
我们的代码现在如下所示:
const updateWords = wordFn => sentence => sentence.split(/\s+/).map(wordFn).join(' ')
const reverseWord = word => word.split('').reverse().join('')
const reverseIfGte5 = word => word.length >= 5 ? reverseWord(word) : word
const spinWords = updateWords(reverseIfGte5)
这些功能的重用性从最高可能到最低。
请注意,使用此类可重用功能时,此处的总代码比此普通版本要长一点:
const spinWords = sentence => sentence.split(/\s+/).map(
word => word.length >= 5 ? word.split('').reverse().join('') : word
).join(' ')
但是我们的版本有几个优点。显然,可重用性是其中之一。但是另一个问题是,将问题分解成小块,如果我们发现问题,就知道在哪里寻找解决方案。
猜测一下,实际上该解决方案中存在潜在的错误。
如果使用'Hey fellow warriors'
调用此函数,则返回'Hey wollef oirraw'
而不是预期的'Hey wollef sroirraw'
。我们的间隔已经关闭。
因为此问题被分解为不同的功能,所以为了解决此问题,我们无需更改哪个功能。显然,它是负责分解updateWords
并将句子重新组合在一起的功能。有一个简单的解决方法,从
const updateWords = wordFn => sentence => sentence.split(/\s+/).map(wordFn).join(' ')
到
const updateWords = wordFn => sentence => sentence.split(' ').map(wordFn).join(' ')
,但是最好使用来自certainPerformance的答案的变体,并像这样重写它:
const updateWords = wordFn => sentence => sentence.replace(/\w+/g, wordFn)
这可以修复错误,并且实际处理的案例比我们原来可以处理的更多。 (请注意,它现在也处理标点符号):
spinWords('Hey, fellow warriors!') //=> 'Hey, wollef sroirraw!'
重要的一点是,为了修复我们的错误,我们能够隔离负责的功能并对其进行更改,而无需进行其他任何更改。
这是我们到达的:
const updateWords = wordFn => sentence => sentence.replace(/\w+/g, wordFn)
const reverseWord = word => word.split('').reverse().join('')
const reverseIfGte5 = word => word.length >= 5 ? reverseWord(word) : word
const spinWords = updateWords(reverseIfGte5)
console.log(spinWords('Hey, fellow warriors!'))
我们已将问题分解为两个相当可重用的函数(reverseWord
和updateWords
),以及两个非常特定于我们问题的函数(reverseIfGte5
和spinWords
。)责任明确,并且易于隔离测试。
就我可能会使用的这个功能而言。但是由于我的个人图书馆经常包含一个函数when
,它已经是其中一个的概括,所以有时我可能更愿意在此基础上进行构建:
const when = (cond, then) => val => cond(val) ? then(val) : val
const reverseIfGte5 = when(word => word.length >= 5, reverseWord)
我之所以创建when
是因为有时如果某些条件为真,我想使用输入的变更版本,而如果条件为假,则不更改地使用它。这正是reverseIfGte5
所要做的,因此将其构建在when
之上非常有用。
这是实用程序库的构建方式。几个特定的问题具有明显的联系,并且针对它们编写了更通用的解决方案来处理它们。如果这些解决方案足够通用,那么它们将成为您个人图书馆或团队图书馆中的候选者。而且,如果它们对更广泛的受众有用,它们可能会包含在通用工具库中。
我是Ramda(这是一个用于JS中的函数编程的实用程序库)的作者之一,而这正是它的构建方式。