Simple question, looping through each character in a string

how can I accomplish something like this in ruby:

pseudo code:

word = "picture"
for( i = 0; i < word.length; i++ )
{
    puts( word.substr(i,1) )
}

ruby?

I've tried something like:

word = "picture"
word.each { |char| puts char }

but that doesn't do what I am wanting. it ends up just putting the
entire word "picture"

I've also tried:

word = "picture"
for i in 0..word.length - 1
puts word[i]
end

that just puts out ascii numbers..

I thought strings could be access like arrays?
word = "picture"
puts word[0] -> 116

thanks all

-rubynube

Hi --

how can I accomplish something like this in ruby:

pseudo code:

word = "picture"
for( i = 0; i < word.length; i++ )
{
   puts( word.substr(i,1) )
}

There's an each_byte iterator. It gives you ASCII values, so you have
to convert them:

   word = "picture"
   word.each_byte {|b| puts b.chr }

You can also do:

   word.split(//).each {|char| puts char }

(Note that this is an area of Ruby that's undergoing a lot of changes
in the transition from 1.8 to 1.9/2.0.)

David

···

On Fri, 1 Dec 2006, warhero wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

What I do is this:

    the_string.scan(/./).each do |char|

However, do note that, as others have said, in Ruby 1.9 this will no
longer be necessary (though it will still work). m.

···

warhero <beingthexemplarylists@gmail.com> wrote:

how can I accomplish something like this in ruby:

pseudo code:

word = "picture"
for( i = 0; i < word.length; i++ )
{
    puts( word.substr(i,1) )
}

ruby?

I've tried something like:

word = "picture"
word.each { |char| puts char }

but that doesn't do what I am wanting. it ends up just putting the
entire word "picture"

I've also tried:

word = "picture"
for i in 0..word.length - 1
puts word[i]
end

that just puts out ascii numbers..

I thought strings could be access like arrays?
word = "picture"
puts word[0] -> 116

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

i've never seen a split('//'). what exactly is that doing?

thanks

···

On Nov 30, 2:13 pm, dbl...@wobblini.net wrote:

Hi --

On Fri, 1 Dec 2006, warhero wrote:
> how can I accomplish something like this in ruby:

> pseudo code:

> word = "picture"
> for( i = 0; i < word.length; i++ )
> {
> puts( word.substr(i,1) )
> }There's an each_byte iterator. It gives you ASCII values, so you have
to convert them:

   word = "picture"
   word.each_byte {|b| puts b.chr }

You can also do:

   word.split(//).each {|char| puts char }

(Note that this is an area of Ruby that's undergoing a lot of changes
in the transition from 1.8 to 1.9/2.0.)

David

--
                   David A. Black | dbl...@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1]http://www.manning.com/black| [3]http://www.rubypowerandlight.com
[2]http://dablog.rubypal.com | [4]http://www.rubycentral.org

Or without the Array:

word.scan(/./m) { |char| ... }

Or you can load the each_char() method from the standard library:

require "jcode"
word.each_char { |char| ... }

James Edward Gray II

···

On Nov 30, 2006, at 1:13 PM, dblack@wobblini.net wrote:

You can also do:

  word.split(//).each {|char| puts char }

does anyone know how you will accomplish the same thing in ruby 1.9?

···

On Nov 30, 3:09 pm, m...@tidbits.com (matt neuburg) wrote:

warhero <beingthexemplaryli...@gmail.com> wrote:
> how can I accomplish something like this in ruby:

> pseudo code:

> word = "picture"
> for( i = 0; i < word.length; i++ )
> {
> puts( word.substr(i,1) )
> }

> ruby?

> I've tried something like:

> word = "picture"
> word.each { |char| puts char }

> but that doesn't do what I am wanting. it ends up just putting the
> entire word "picture"

> I've also tried:

> word = "picture"
> for i in 0..word.length - 1
> puts word[i]
> end

> that just puts out ascii numbers..

> I thought strings could be access like arrays?
> word = "picture"
> puts word[0] -> 116What I do is this:

    the_string.scan(/./).each do |char|

However, do note that, as others have said, in Ruby 1.9 this will no
longer be necessary (though it will still work). m.

--
matt neuburg, phd = m...@tidbits.com,Matt Neuburg’s Home Page
Tiger -http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript -http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart.http://www.tidbits.com

In the immortal words of Homer Simpson, "Doh!"

I've always thought that that method never existed: always looked for
a Int#to_char.

Don't I feel dumb now =)

···

On 11/30/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

There's an each_byte iterator. It gives you ASCII values, so you have
to convert them:

   word = "picture"
   word.each_byte {|b| puts b.chr }

--
Lou.

matt neuburg wrote:
...

What I do is this:

    the_string.scan(/./).each do |char|

However, do note that, as others have said, in Ruby 1.9 this will no
longer be necessary (though it will still work). m.

FWIW
Since it comes up from time to time I was curious how much performance difference there was between using scan, split, and each_byte. The results surprised me. From my blog post here is what I found:

irb(main):026:0> Benchmark.bm do |bm|
irb(main):027:1* bm.report("split:") { 10000.times do a = "1234567890".split('') end }
irb(main):028:1> bm.report(" scan:") { 10000.times do a = "1234567890".scan(/./) end }
irb(main):029:1> bm.report(" eb:") { 10000.times do "1234567890".each_byte { |by| (a ||= ) << by } end }
irb(main):030:1> end
      user system total real
split: 0.320000 0.000000 0.320000 ( 0.321568)
scan: 0.200000 0.000000 0.200000 ( 0.210951)
   eb: 0.260000 0.030000 0.290000 ( 0.345428)

So, I am surprised that scan was faster, did you guess that? I wonder if pre-compiling the regex will make it even faster?

irb(main):033:0> Benchmark.bm do |bm|
irb(main):034:1* bm.report("split:") { 10000.times do a = "1234567890".split('') end }
irb(main):035:1> bm.report(" scan:") { 10000.times do a = "1234567890".scan(rx) end }
irb(main):036:1> bm.report(" eb:") { 10000.times do "1234567890".each_byte { |by| (a ||= ) << by } end }
irb(main):037:1> end
      user system total real
split: 0.280000 0.010000 0.290000 ( 0.292449)
scan: 0.180000 0.000000 0.180000 ( 0.180988)
   eb: 0.280000 0.050000 0.330000 ( 0.367461)
It sure did, huh. As an aside in the book "The Ruby Way" second edition Hal uses scan in the Strings chapter not mentioning split, but does show each_byte. I also wonder if how size of the string changes the benchmark.

Johnny P
http://ruby-talk.blogspot.com/

Aaron Smith wrote:

i've never seen a split('//'). what exactly is that doing?

thanks

split will return an array of strings, splitting the initial string at
any point that matches the supplied regex.

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

You can also do:

  word.split(//).each {|char| puts char }

Or without the Array:

word.scan(/./m) { |char| ... }

And, I now realize, if someone posted what I posted and I were
responding to it, I would point out that:

   array.each {|e| puts e }

is the same as:

   puts array

Something I've described in the past as a nuby rite of passage, I
believe... :slight_smile:

Or you can load the each_char() method from the standard library:

require "jcode"
word.each_char { |char| ... }

I don't think I've ever seen that one. So why is everyone so vexed
about what's going to happen with this in 1.9? :slight_smile: (I know... it's
not that simple.)

David

···

On Fri, 1 Dec 2006, James Edward Gray II wrote:

On Nov 30, 2006, at 1:13 PM, dblack@wobblini.net wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Yes, I saw the each_char method in the RDocs but when I tried using it,
it gave me an error. Now I see I had to load it. i'll try that.

thanks.

···

On Nov 30, 2:29 pm, James Edward Gray II <j...@grayproductions.net> wrote:

On Nov 30, 2006, at 1:13 PM, dbl...@wobblini.net wrote:

> You can also do:

> word.split(//).each {|char| puts char }Or without the Array:

word.scan(/./m) { |char| ... }

Or you can load the each_char() method from the standard library:

require "jcode"
word.each_char { |char| ... }

James Edward Gray II

does it make sense to have a method for String in a file called
jcode.rb? I'm just getting into ruby, I haven't had to do a lot yet
where I needed t require some other libraries. is all of ruby have
weird names for where code is?

···

On Nov 30, 2:29 pm, James Edward Gray II <j...@grayproductions.net> wrote:

On Nov 30, 2006, at 1:13 PM, dbl...@wobblini.net wrote:

> You can also do:

> word.split(//).each {|char| puts char }Or without the Array:

word.scan(/./m) { |char| ... }

Or you can load the each_char() method from the standard library:

require "jcode"
word.each_char { |char| ... }

James Edward Gray II

warhero wrote:

does anyone know how you will accomplish the same thing in ruby 1.9?

  str.chars.each |c| ...

T.

warhero wrote:

does anyone know how you will accomplish the same thing in ruby 1.9?

1. Please don't top post.

2. Did you read the post you are replying to? The previous poster said it
will still work under Ruby 1.9. His remark was that it will no longer
be /necessary/.

Here is the quote:

···

However, do note that, as others have said, in Ruby 1.9 this will no
longer be necessary (though it will still work). m.

--
Paul Lutus
http://www.arachnoid.com

I'd be curious to know what happens if you specify that this is a UTF-8
string. (Of course in that case each_byte can't be used at all.) m.

···

John Pywtorak <jpywtora@calpoly.edu> wrote:

matt neuburg wrote:
..
> What I do is this:
>
> the_string.scan(/./).each do |char|
>
> However, do note that, as others have said, in Ruby 1.9 this will no
> longer be necessary (though it will still work). m.
>

FWIW
Since it comes up from time to time I was curious how much performance
difference there was between using scan, split, and each_byte. The
results surprised me. From my blog post here is what I found:

irb(main):026:0> Benchmark.bm do |bm|
irb(main):027:1* bm.report("split:") { 10000.times do a =
"1234567890".split('') end }
irb(main):028:1> bm.report(" scan:") { 10000.times do a =
"1234567890".scan(/./) end }
irb(main):029:1> bm.report(" eb:") { 10000.times do
"1234567890".each_byte { |by| (a ||= ) << by } end }
irb(main):030:1> end
      user system total real
split: 0.320000 0.000000 0.320000 ( 0.321568)
scan: 0.200000 0.000000 0.200000 ( 0.210951)
   eb: 0.260000 0.030000 0.290000 ( 0.345428)

So, I am surprised that scan was faster, did you guess that? I wonder if
pre-compiling the regex will make it even faster?

irb(main):033:0> Benchmark.bm do |bm|
irb(main):034:1* bm.report("split:") { 10000.times do a =
"1234567890".split('') end }
irb(main):035:1> bm.report(" scan:") { 10000.times do a =
"1234567890".scan(rx) end }
irb(main):036:1> bm.report(" eb:") { 10000.times do
"1234567890".each_byte { |by| (a ||= ) << by } end }
irb(main):037:1> end
      user system total real
split: 0.280000 0.010000 0.290000 ( 0.292449)
scan: 0.180000 0.000000 0.180000 ( 0.180988)
   eb: 0.280000 0.050000 0.330000 ( 0.367461)
It sure did, huh. As an aside in the book "The Ruby Way" second edition
Hal uses scan in the Strings chapter not mentioning split, but does show
each_byte. I also wonder if how size of the string changes the benchmark.

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

I find it a bit strange that puts treats array objects differently
than all other objects. Strings are simply written to stdout, objects
other than arrays are converted to strings by calling to_s and then written,
but arrays are handled via the recursive algorithm shown above. The effect
is to 'flatten' recursive array structures and then write the to_s version of
each object on a separate line.

My expectation was that Array#to_s would be called for array arguments but it
turns out that Array#to_s doesn't generate the same results as the recursive
algorithm that Dave shows above.

Even more puzzling is that IO#print doesn't treat array objects specially, and
simply calls Array#to_s.

Prior to 1.8, Array#to_s simply concatenated the results of calling #to_s on each
element of the array. In 1.9 Array#to_s generates an inspect-like string for the
array:

  ruby 1.8.5: [1,2].to_s => 12
  ruby 1.9: [1,2].to_s => [1, 2]

  ruby 1.8.5: print [1,2] => 12
         ruby 1.9: print [1,2] => [1, 2]

         ruby 1.8.5: puts [1,2] => 1\n2\n
         ruby 1.9: puts [1,2] => 1\n\2\n

I guess that the puts behavior is in some sense a shortcut for a common need
(instead of writing puts *a.flatten), but it seems anomalous to me.

If you use nested arrays to model a tree structure then Array#to_s is a very nice way to
do a pre-order traversal of the structure generating a textual representation of the tree.
This works just fine in 1.8, but in 1.9 you get burned. I suspect that there might be quite
a bit of code that expects the 1.8 behavior for Array#to_s than the 1.9 behavior.

Maybe I'm missing something but I think to get the 1.8 Array#to_s behavior in 1.9 you would
have to write something like:

  a.flatten.inject("") { |s,i| s << i.to_s }

Gary Wright

···

On Nov 30, 2006, at 2:39 PM, dblack@wobblini.net wrote:

And, I now realize, if someone posted what I posted and I were
responding to it, I would point out that:

  array.each {|e| puts e }

is the same as:

  puts array

Something I've described in the past as a nuby rite of passage, I
believe... :slight_smile:

gwtmp01@mac.com wrote:

Maybe I'm missing something but I think to get the 1.8 Array#to_s behavior in 1.9 you would
have to write something like:
    a.flatten.inject("") { |s,i| s << i.to_s }

a.flatten.join ?

Ah, yes. I knew there had to be an easier way. Still I kind of like the 1.8 behavior of to_s.

Gary Wright

···

On Dec 1, 2006, at 12:19 AM, Devin Mullins wrote:

gwtmp01@mac.com wrote:

Maybe I'm missing something but I think to get the 1.8 Array#to_s behavior in 1.9 you would
have to write something like:
    a.flatten.inject("") { |s,i| s << i.to_s }

a.flatten.join ?