简体   繁体   中英

How do I reverse a string within a for loop?

Im trying to reverse all words with a character count of 5 or more in a given string.

Here is my code:

    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(' ');
}

For some reason, I get the same result. id appreciate some assistance.

for example; input: "Im learning coding everyday" ouput: "Im gninrael gnidoc yadyreve"

The line stringArray[i].split('').reverse().join('') does not reverse in place but returns a new string with the text being reversed. That means that the array itsself stays the same. You need to override the entry at position i with the reversed word to actually get the words reversed. Below is the updated example.

 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"))

While Masheer Ali supplies a straightforward one-liner, I think it's always worth at least considering how to break down such requirements into simpler parts. You may not always use such a breakdown. If the component parts don't seem useful on their own, it might be better to have them inlined into a main function. But often it makes your code simpler and more understandable, and it's worth doing just for that.

Here is such a breakdown:

 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') )

We have three functions.

  • spin reverses a single string. It knows nothing about sentences or a "greater than length 5" restriction. It simply turns something like 'abc x yz' into 'zy x cba' .

  • spinLong reverses only long strings, where the length is supplied as a parameter. That's all it does. It does not know how to flip the string itself, delegating the actual spinning to the function spin . So all it has to do is decide whether your stringis long enough and call spin if it is.

  • spinWords solves the problems that was asked. It spins all the words in the sentence that are more than 5 letters long. But it also doesn't know how to spin a word, and it doesn't know how to check the word length. It delegates that behavior to spinLong . Internally it splits the sentence into words, calls spinLong (5) on each word, and combines them back into a sentence.

We could inline this with code similar to MasheerAli's second version, like this:

const spinWords = (str) => str
  .split (' ') .map ((s) => s .length > 5 ? s .split ('') .reverse () .join ('') : s) .join (' ')

That now looks much less compelling to me. However we choose to lay it out, it will seem more like a bunch of steps than like a description of what we want done. I find the earlier one easier to understand.

Of course you can almost always go further with this style. We could define a makeWords function that splits on spaces, and a makeSentence one that puts such spaces back between words. This is an interesting call. I don't find these particularly compelling, but it might be worth investigating, especially in how we'd glue them together.


Okay, now that you've done such a good job delivering this business-critical functionality, you're boss tells you that there is an important new requirement. For some customers, we will only spin words longer than 7 characters. For another, it's 12.

And you need to hurry this out the door. "I need this in an hour. How soon can you have it done?" (A real quote from an old boss, for a position I left soon after. One hour was actually "next Tuesday", but the point is the same. Bosses seem to think code schedules can simply be created by fiat.) The big problem is that calls all over the system depend now on your beautiful spinWords module. You don't have time to go alter all their calls. But you know that cutting and pasting is a bad idea. You need to fix this at the root.

Well, you can do that easily, without copying and pasting everywhere. We just need a new function with an additional parameter, and a refactoring of spinWords to use it:

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
)

"Ok, boss. That's done. We can decide after this spinning crisis is over whether we want to keep the old spinWords function that only handled 5+-letters words as the default case across the system or refactor everything to replace them with direct calls to our fancy new spinLongWords function. It's fairly low priority, but it should be listed among our tech debt until we make a decision and implement it."

In javascript if you call any method on string it doesn't change that but instead return a new value. You need to store that value in variable and use it.

 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"));

A more fancy wat to do the same this is to use map() and filter()

 const spinWords = string => string.split(' ').map(x => x.length >= 5? x.split('').reverse().join(''): x ).join(' '); console.log(spinWords("Im learning coding everyday"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM