DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #263 - Reverse Words

Complete the function that accepts a string parameter, and reverses each word in the string. All spaces in the string should be retained.

Examples
"This is an example!" ==> "sihT si na !elpmaxe"
"double spaces" ==> "elbuod secaps"

Tests
reverseWords("The quick brown fox jumps over the lazy dog.")
reverseWords("double spaced words")

Good luck!


This challenge comes from jnicol on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (32)

Collapse
Β 
aminnairi profile image
Amin β€’ β€’ Edited

Haskell

import Data.List.Split (split, oneOf)


reverseWords :: String -> String
reverseWords = concatMap reverse . split (oneOf " ")


main :: IO ()
main = do
    print $ reverseWords "One space"        -- "enO ecaps"
    print $ reverseWords "Two  spaces"      -- "owT  secaps"
    print $ reverseWords "Three   spaces"   -- "eerhT   secaps"
Collapse
Β 
oleksandrriabukha profile image
Oleksandr Riabukha β€’

Without libraries:
reverseWords = unwords . map reverse . words

Collapse
Β 
aminnairi profile image
Amin β€’ β€’ Edited

This looks very clean, well done. I think I would have gone for that one if keeping spaces wasn't an issue, but it is in this challenge.

The second code example from this post is wrong in the sense that spaces must be kept, and only a few provided solutions here are working because the example was not clear enough on what was expected.

- "double spaces" ==> "elbuod secaps"
+ "double  spaces" ==> "elbuod  secaps"

I always lookup for the original challenge in Codewars to get a better specification to what I'm supposed to provide as a valid solution.

Original challenge specification.

Collapse
Β 
olekria profile image
Olek Ria β€’

Very elegant.

Collapse
Β 
astagi profile image
Andrea Stagi β€’

For Python, one line

def reverse_words(sentence: str) -> str:
    return ' '.join(sentence.split(' ')[::-1])[::-1]
Collapse
Β 
rafaacioly profile image
Rafael Acioly β€’

Well done! It could also be

return ' '.join(word[::-1] for word in sentence.split() if not word.isspace())
Collapse
Β 
astagi profile image
Andrea Stagi β€’

Looks great :)

Collapse
Β 
agtoever profile image
agtoever β€’

I think this would fail with doubles spaces in a sentence...

Thread Thread
Β 
astagi profile image
Andrea Stagi β€’ β€’ Edited

That's true :( looks like the right implementation is

def reverse_words(sentence: str) -> str:
    return ' '.join(word[::-1] for word in sentence.split())
Thread Thread
Β 
rafaacioly profile image
Rafael Acioly β€’

you don't need to use (' ') to split by spaces :)

Thread Thread
Β 
astagi profile image
Andrea Stagi β€’

That's what happens when you write too much js code πŸ˜… edited thanks!

Collapse
Β 
dry profile image
Hayden Mankin β€’

Javascript

let reverseWords = (str) => str.replace(/\S+/g, word => [...word].reverse().join(""));

console.log(reverseWords("The quick brown fox jumps over the lazy dog.")); // ehT kciuq nworb xof spmuj revo eht yzal .god
console.log(reverseWords("double spaced words")); // elbuod decaps sdrow
console.log(reverseWords("πŸž€πŸžπŸž‚πŸžƒ")); // πŸžƒπŸž‚πŸžπŸž€

I avoided split("") as it breaks with non BMP characters. The spread operator works just as well for splitting strings into individual characters and won't break astral characters.

Notice how if I use split the output is messed up on my last test case.

let reverseWords = (str) => str.replace(/\S+/g, word => word.split("").reverse().join(""));

console.log(reverseWords("The quick brown fox jumps over the lazy dog.")); // ehT kciuq nworb xof spmuj revo eht yzal .god
console.log(reverseWords("double spaced words")); // elbuod decaps sdrow
console.log(reverseWords("πŸž€πŸžπŸž‚πŸžƒ")); // οΏ½πŸž‚πŸžπŸž€οΏ½
Collapse
Β 
hungthai1401 profile image
Thai Nguyen Hung β€’

For php

function reverseWords($words) {
    $pattern = '/\S+/';
    return preg_replace_callback(
        $pattern,
        function ($word) {
            return strrev($word[0]);
        },
        $words
    );
}

echo reverseWords('The quick brown fox jumps over the lazy dog.');
echo reverseWords('double spaced words');
Collapse
Β 
peter279k profile image
peter279k β€’ β€’ Edited

Here are the PHP codes about using foreach and for loops to complete:

function reverseWords($str) {
  $strArray = explode(' ', $str);
  $reveresedArray = [];

  foreach($strArray as $string) {
    $reversedStr = '';
    for($index=strlen($string)-1; $index>=0; $index--) {
       $reversedStr .= $string[$index];
    }

    $reversedArray[] = $reversedStr;
  }

  return implode(' ', $reversedArray);
}
Collapse
Β 
boris profile image
Boris Quiroz β€’

More python:

def reverseWords(words):
    r = ""
    for word in words.split():
        r += "{} ".format(word[::-1])

    print(r)

reverseWords("The quick brown fox jumps over the lazy dog.")
reverseWords("double spaced words")
Collapse
Β 
sam_ferree profile image
Sam Ferree β€’

Befunge-93

This version current works if the end of input pushes -1 on the stack (due to the interpreter I used), change 3 characters and it works for a carriage return

0v
 >~:01--!#v_:84*-!   #v_
 ^        >$84*>,:#v_@>,:#v_
               ^   <  ^   <
Collapse
Β 
k776 profile image
Kieran Pilkington β€’

Or more simply:

def reverse_words(str)
  str.split.map(&:reverse).join(" ")
end
Collapse
Β 
dancouper profile image
Dan Couper β€’ β€’ Edited

JavaScript (imperative & linear):

function reverseWords(str) {
  let wordbuf = "";
  let outbuf = "";

  for (let char of str) {
    // NOTE replace with `if (/\s/.test(char))`
    // if anything other than ASCII whitespace
    // char expected
    if (char === " ") {
      outbuf += (wordbuf + char);
      wordbuf = "";
    } else {
      wordbuf = char + wordbuf;
    }
  }
  outbuf += wordbuf;

  return outbuf;
}
Collapse
Β 
hans5958 profile image
Hans5958 β€’ β€’ Edited

JavaScript (ES6) (golf)

const reverseWords = i=>i.split` `.map(w=>w.split``.sort(_=>1).join``).join` `
const reverseWords = i=>i.replace(/\w+/g,w=>[...w].sort(_=>1).join``)