simple question, looping through each character in a string

Discussion in 'Ruby' started by warhero, Nov 30, 2006.

  1. warhero

    warhero Guest

    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
    end

    that just puts out ascii numbers..

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


    thanks all

    -rubynube
    warhero, Nov 30, 2006
    #1
    1. Advertising

  2. warhero

    Guest

    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 |
    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
    , Nov 30, 2006
    #2
    1. Advertising

  3. warhero

    warhero Guest

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

    thanks



    On Nov 30, 2:13 pm, 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 |
    > 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
    warhero, Nov 30, 2006
    #3
  4. warhero

    Drew Olson Guest

    Re: simple question, looping through each character in a str

    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/.
    Drew Olson, Nov 30, 2006
    #4
  5. On Nov 30, 2006, at 1:13 PM, 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
    James Edward Gray II, Nov 30, 2006
    #5
  6. warhero

    Guest

    Hi --

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

    > On Nov 30, 2006, at 1:13 PM, 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... :)

    > 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? :) (I know... it's
    not that simple.)


    David

    --
    David A. Black |
    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
    , Nov 30, 2006
    #6
  7. warhero

    warhero Guest

    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 <>
    wrote:
    > On Nov 30, 2006, at 1:13 PM, 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, Nov 30, 2006
    #7
  8. warhero

    warhero Guest

    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 <>
    wrote:
    > On Nov 30, 2006, at 1:13 PM, 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, Nov 30, 2006
    #8
  9. warhero

    matt neuburg Guest

    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) )
    > }
    >
    >
    > 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
    > end
    >
    > that just puts out ascii numbers..
    >
    > I thought strings could be access like arrays?
    > word = "picture"
    > 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.

    --
    matt neuburg, phd = , http://www.tidbits.com/matt/
    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
    matt neuburg, Nov 30, 2006
    #9
  10. warhero

    warhero Guest

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



    On Nov 30, 3:09 pm, (matt neuburg) wrote:
    > 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) )
    > > }

    >
    > > 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
    > > 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 = ,http://www.tidbits.com/matt/
    > 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
    warhero, Nov 30, 2006
    #10
  11. warhero

    Trans Guest

    warhero wrote:
    > does anyone know how you will accomplish the same thing in ruby 1.9?


    str.chars.each |c| ...

    T.
    Trans, Nov 30, 2006
    #11
  12. On 11/30/06, <> 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 Simpson, "Doh!"

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

    Don't I feel dumb now =)


    --
    Lou.
    Louis J Scoras, Nov 30, 2006
    #12
  13. 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/
    John Pywtorak, Dec 1, 2006
    #13
  14. warhero

    Guest

    puts, print, Array#to_s relative to ruby 1.8 and 1.9

    On Nov 30, 2006, at 2:39 PM, 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... :)


    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
    , Dec 1, 2006
    #14
  15. Re: puts, print, Array#to_s relative to ruby 1.8 and 1.9

    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 ?
    Devin Mullins, Dec 1, 2006
    #15
  16. warhero

    Guest

    Re: puts, print, Array#to_s relative to ruby 1.8 and 1.9

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

    > 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
    , Dec 1, 2006
    #16
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Curts
    Replies:
    1
    Views:
    321
    Lee Fesperman
    Aug 21, 2003
  2. Ralph Hartman
    Replies:
    1
    Views:
    201
    Raghavendra T V
    Aug 25, 2004
  3. Victor
    Replies:
    3
    Views:
    128
    Victor
    Sep 12, 2003
  4. Aaron
    Replies:
    2
    Views:
    519
    dhtml
    Apr 10, 2011
  5. Replies:
    5
    Views:
    271
Loading...

Share This Page