hfesoio
hfesoio

Reputation: 29

Why isn't the following code working the way it should?

array = ["car","carrs"]
array.each { |x|
x.capitalize
}

I have tried doing with do too by removing the curly braces and adding do after .each, I have also tried for each in array, but that didnt work too. Am i doing something wrong because nothing gets capitalized?

Upvotes: 1

Views: 50

Answers (2)

KSD Putra
KSD Putra

Reputation: 497

You have to understand the difference between map vs each. You can read it here.

For those who don't want to read that:

Each is like a more primitive version of map. It gives you every element so you can work with it, but it doesn’t collect the results. Each always returns the original, unchanged object. While map does the same thing, but. It returns a new array with the transformed elements.

So, you have to use map in order to return a new array:

array = ["car","carrs"]
capitalized_array = array.map { |x| x.capitalize }

# or

array = ["car","carrs"]
array.map! { |x| x.capitalize }

Now, what is the different between map and map!? We need to read the documentation

map invokes the given block once for each element of self. Creates a new array containing the values returned by the block. While map! invokes the given block once for each element of self, replacing the element with the value returned by the block.

Upvotes: 3

Chris Heald
Chris Heald

Reputation: 62648

String#capitalize returns a copy of the object with the first letter capitalized. What you're basically doing is looping through your array and generating new copies of the strings, but then immediately throwing them away.

You have a couple of ways to approach this:

  1. You can use #map rather than #each to take each result of your loop block body and collect it into a new array:
array = ["car","carrs"]
capitalized_array = array.map { |x| x.capitalize }
  1. Or, if you actually want to mutate the original strings, use String#capitalize! rather than capitalize, which mutates the input object, rather than returning a new object:
array = ["car","carrs"]
array.each { |x| x.capitalize! }

While it may seem tempting to use the mutative version, it is frequently a good idea to use non-mutative methods to produce transformations of your data, so you don't lose your original input data. Mutate-in-place can introduce subtle bugs by making the state of the data harder to reason about.

Upvotes: 5

Related Questions