Iterating through a string

If I try the following…

“I love guitar playing”.split {|s| s.capitalize}.join(" ")

I would expect it to capitalize the first letter of each word but it
doesn’t seem to work.

Any hints on what I’m doing incorrectly?

Alle Sunday 21 September 2008, Jody Glidden ha scritto:

If I try the following…

“I love guitar playing”.split {|s| s.capitalize}.join(" ")

I would expect it to capitalize the first letter of each word but it
doesn’t seem to work.

Any hints on what I’m doing incorrectly?

String#split doesn’t take a block, so that the block you pass to it is
ignored. What you wrote is equivalent to

“I love guitar playing”.split.join(" ")

To do what you want, you need to call map on the array returned by
String#split:

“I love guitar playing”.split.map{|s| s.capitalize}.join(" ")

I hope this helps

Stefano

Stefano C. wrote:

Alle Sunday 21 September 2008, Jody Glidden ha scritto:

If I try the following…

“I love guitar playing”.split {|s| s.capitalize}.join(" ")

I would expect it to capitalize the first letter of each word but it
doesn’t seem to work.

Any hints on what I’m doing incorrectly?

String#split doesn’t take a block, so that the block you pass to it is
ignored. What you wrote is equivalent to

“I love guitar playing”.split.join(" ")

To do what you want, you need to call map on the array returned by
String#split:

“I love guitar playing”.split.map{|s| s.capitalize}.join(" ")

I hope this helps

Stefano

Ahh, I understand. I must have missed the map/collect functionality.

Thanks.

Ruby F. wrote:

Stefano C. wrote:

Alle Sunday 21 September 2008, Jody Glidden ha scritto:

If I try the following…

“I love guitar playing”.split {|s| s.capitalize}.join(" ")

I would expect it to capitalize the first letter of each word but it
doesn’t seem to work.

Any hints on what I’m doing incorrectly?

String#split doesn’t take a block, so that the block you pass to it is
ignored. What you wrote is equivalent to

“I love guitar playing”.split.join(" ")

To do what you want, you need to call map on the array returned by
String#split:

“I love guitar playing”.split.map{|s| s.capitalize}.join(" ")

I hope this helps

Stefano

Ahh, I understand. I must have missed the map/collect functionality.

Thanks.

“I love guitar playing”.split.each{|s| s.capitalize}.join(" ")

does not work because #capitalize does not modify the original; it gives
you a copy. Map/collect really collects these copies, #each does not.
However

“I love guitar playing”.split.each{|s| s.capitalize!}.join(" ")

Does work, because the self-modifying #capitalize! is available.
Personally I’m starting to prefer #map , also because of this:

a = (1…9).map{|n| n*n}

#versus my old way

a = [] #annoying
(1…9).each{|n| a<<n*n}

Regards,

Siep

Jody Glidden wrote:

If I try the following…

“I love guitar playing”.split {|s| s.capitalize}.join(" ")

I would expect it to capitalize the first letter of each word but it
doesn’t seem to work.

“I love guitar playing”.gsub( /\S+/ ){|s| s.capitalize}
==>“I Love Guitar Playing”

On Mon, Sep 22, 2008 at 6:37 AM, William J. [email protected]
wrote:

“I love guitar playing”.gsub( /\S+/ ){|s| s.capitalize}
==>“I Love Guitar Playing”

it would be great if #split accept a block, too

On Sunday 21 September 2008 06:37 pm, William J. wrote:

Jody Glidden wrote:

If I try the following…

“I love guitar playing”.split {|s| s.capitalize}.join(" ")

I would expect it to capitalize the first letter of each word but it
doesn’t seem to work.

Just for kicks, I managed to modify your approach to make it work (at
least in irb):

“I love guitar playing”.split.each {|s| s.capitalize!}.join(" ")

So, it took the addition of each to cause the block to actually do
something, and switching from capitalize to capitalize! (Which, iiuc,
causes the original object to be changed, rather than creating a new
changed object.

Try substituting things like puts “test” in the body of the block to
experiment.

Randy K.

On Sep 21, 2008, at 7:32 PM, botp wrote:

it would be great if #split accept a block, too

When “.map” is only another 4 characters, is it worth the pollution?

It’s an easy monkey-patch, though.

Stephen

Siep K. wrote:

a = (1…9).map{|n| n*n}

#versus my old way

a = [] #annoying
(1…9).each{|n| a<<n*n}

FYI, there’s another pattern for “building the result” without the
annoying assignment:

a = (1…9).inject([]) { |acc,n| acc << n*n }

Or in a more functional style (without any array mutation)

a = (1…9).inject([]) { |acc,n| acc + [n*n] }

However in this case, map is perfectly appropriate. inject is useful
when you’re building something that isn’t an Array - for example a
String or a Hash.

From: Stephen C. [mailto:[email protected]]

When “.map” is only another 4 characters, is it worth the pollution?

that’s a 2 pass