Start learning free

LESSON 271 OF 677 · TUPLES, SORTING & BUILT-INS

Shout The Words in Scala: Using map on an ArrayBuffer

Practice Read the full explanation

You get an ArrayBuffer called words. Each word in it is in lowercase letters.

Return a new ArrayBuffer with every word shouted.

To shout a word, write it in capital letters and put ! after it. So "hey" becomes "HEY!".

Keep the words in the same order.

 

Example 1:

Input: words = ["hey", "you"]
Output: ["HEY!", "YOU!"]
Explanation: Both words are in capital letters now.
Each one has a ! at the end.

Example 2:

Input: words = ["go"]
Output: ["GO!"]
Explanation: One word goes in, one word comes out.

Example 3:

Input: words = ["no", "no", "no"]
Output: ["NO!", "NO!", "NO!"]
Explanation: A word that repeats is shouted each time.

 

Constraints:

  • words has at least one word.
  • Every word has only the letters a to z.
STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · TUPLES, SORTING & BUILT-INS

    Shout The Words in Scala, explained

    Problem overview

    shout gets an ArrayBuffer[String] called words, with lowercase words. It returns a new buffer with every word shouted: in capital letters, with ! after it. The order stays the same.

    • ["hey", "you"] gives ["HEY!", "YOU!"].
    • ["go"] gives ["GO!"].
    • ["no", "no", "no"] gives ["NO!", "NO!", "NO!"], because a repeated word is shouted each time.

    Approach

    Every word becomes exactly one new word in the same place. That is what map is for. You write the change for one word, and map applies it to each word and collects the results in a new ArrayBuffer. The change is: make the word uppercase, then add "!" at the end.

    Step by step

    1. Call map on words with a function that turns each word into word.toUpperCase + "!". Keep the result in a val named shouted.
    2. Return shouted.

    The solution in Scala

    class Solution {
        def shout(words: ArrayBuffer[String]): ArrayBuffer[String] = {
            val shouted = words.map(word => word.toUpperCase + "!")
            return shouted
        }
    }
    

    Details worth knowing:

    • toUpperCase returns a new string. Strings can't be changed, so word itself stays lowercase. It is written without parentheses here; toUpperCase() works too and gives the same result.
    • The + joins two strings. Without parentheses around the call, word.toUpperCase + "!" means "the uppercase word, then !".
    • The new buffer has as many items as words. For the first example, shouted has 2 items.
    • words is not changed. map returns a new buffer.

    The same thing with a loop

    Before map, you would build the result with a loop and an empty buffer:

    val shouted = ArrayBuffer[String]()
    for (word <- words) {
        shouted += word.toUpperCase + "!"
    }
    

    For ["hey", "you"] this also gives ArrayBuffer(HEY!, YOU!). The loop and map do the same work: map creates the empty buffer, visits each item in order, adds one answer per item and hands the buffer back. When every item turns into exactly one new item, the one-line map says that directly, and there is nothing to get wrong in the setup.

    Testing

    ["hey", "you"]       ArrayBuffer(HEY!, YOU!)
    ["go"]               ArrayBuffer(GO!)
    ["no", "no", "no"]   ArrayBuffer(NO!, NO!, NO!)
    

    Another way

    Scala lets you shorten the function with an underscore: words.map(_.toUpperCase + "!") gives ArrayBuffer(HEY!, YOU!) for the first example. The underscore stands for the single argument. Naming it word, as the lesson does, is easier to read while you are learning.

    Types and edge cases

    The function's return type is ArrayBuffer[String]. Scala works out the type of shouted from the function you gave map: it returns a String for each word, so the result is an ArrayBuffer[String], and it matches the declared return type without any extra code.

    The input always has at least one word, and every word uses only the letters a to z. That means there is nothing to special-case: no empty buffer, no digits or spaces. A word that is already in capitals would be unchanged by toUpperCase, so "Hey" would also become "HEY!".

    The order of the two steps does not change the result here. Adding the ! first and then calling toUpperCase gives the same words, because the exclamation mark has no uppercase form.

    Common mistakes

    • Using filter. Nothing is removed here. Every word must be in the result.
    • Forgetting the !, or putting it before the word. It goes after.
    • Not saving the result. words.map(...) alone doesn't change words. Return the new buffer.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free