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 –

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

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

thanks

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

Hi –

On Fri, 1 Dec 2006, James Edward G. II wrote:

On Nov 30, 2006, at 1:13 PM, [email protected] wrote:

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

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 G. II [email protected]

On Nov 30, 2006, at 1:13 PM, [email protected] 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 G. 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 G. II [email protected]

warhero [email protected] wrote:

I’ve also tried:
puts word[0] → 116
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.

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

warhero wrote:

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

str.chars.each |c| …

T.

On 11/30/06, [email protected] [email protected] 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 }

In the immortal words of Homer S., “Doh!”

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

Don’t I feel dumb now =)

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:

John P. [email protected] wrote:

FWIW
“1234567890”.each_byte { |by| (a ||= []) << by } end }
irb(main):034:1* bm.report(“split:”) { 10000.times do a =
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.

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.

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/

On Nov 30, 2006, at 2:39 PM, [email protected] wrote:

believe… :slight_smile:
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 W.

[email protected] 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 ?

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

[email protected] 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 W.