取一个字符串并反转某些单词-Javascript

时间:2018-12-30 23:01:10

标签: javascript arrays string

编写一个函数,该函数接受一个或多个单词的字符串,并返回相同的字符串,但五个或多个字母单词全部颠倒。传入的字符串将仅包含字母和空格。仅当存在多个单词时才包含空格。

我编写的代码将整个字符串反向。我相信它与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");

2 个答案:

答案 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!'))

我们已将问题分解为两个相当可重用的函数(reverseWordupdateWords),以及两个非常特定于我们问题的函数(reverseIfGte5spinWords。)责任明确,并且易于隔离测试。

进一步扩展

就我可能会使用的这个功能而言。但是由于我的个人图书馆经常包含一个函数when,它已经是其中一个的概括,所以有时我可能更愿意在此基础上进行构建:

const when = (cond, then) => val => cond(val) ? then(val) : val
const reverseIfGte5 = when(word => word.length >= 5, reverseWord)

我之所以创建when是因为有时如果某些条件为真,我想使用输入的变更版本,而如果条件为假,则不更改地使用它。这正是reverseIfGte5所要做的,因此将其构建在when之上非常有用。

这是实用程序库的构建方式。几个特定的​​问题具有明显的联系,并且针对它们编写了更通用的解决方案来处理它们。如果这些解决方案足够通用,那么它们将成为您个人图书馆或团队图书馆中的候选者。而且,如果它们对更广泛的受众有用,它们可能会包含在通用工具库中。

我是Ramda(这是一个用于JS中的函数编程的实用程序库)的作者之一,而这正是它的构建方式。

相关问题