Iterating through a string

J

Jody Glidden

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?
 
S

Stefano Crocco

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
 
R

Ruby Fan

Stefano said:
Alle Sunday 21 September 2008, Jody Glidden ha scritto:


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.
 
S

Siep Korteling

Ruby said:
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
 
W

William James

Jody said:
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"
 
R

Randy Kramer

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 Kramer
 
S

Stephen Celis

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
 
B

Brian Candler

Siep said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,277
Latest member
VytoKetoReview

Latest Threads

Top