Forum: Ruby Array : each_with_index

41918fc34e4c3a365eabbd04ba9b551d?d=identicon&s=25 Vin Raja (vineetraja)
on 2007-07-19 08:46
Hi All,

I have following lines


m=['a','b','c']
puts m.each_with_index{|v,i| i}

which output in:

>ruby try.rb
a
b
c
>Exit code: 0



I was expecting to see indexes, rather than values.
Am I overlooking some trivial nuance or what.
Basically i wanted to print index values while iterating an array at
some other project.
and "each_with_index" seemed very obvious for the task but for the
unexpected result.

Raja
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-19 08:51
(Received via mailing list)
2007/7/19, Vin Raja <vineetraja@gmail.com>:
> >ruby try.rb
> some other project.
> and "each_with_index" seemed very obvious for the task but for the
> unexpected result.

It is. But #each_with_index *returns* the Enumerable.  You need to put
the put into the block:

irb(main):001:0> ['a','b','c'].each_with_index {|a,i| puts i}
0
1
2
=> ["a", "b", "c"]
irb(main):002:0>

Kind regards

robert
Cee0292fffa691f1fb320d5400200e99?d=identicon&s=25 Marcel Molina Jr. (Guest)
on 2007-07-19 08:53
(Received via mailing list)
On Thu, Jul 19, 2007 at 03:46:10PM +0900, Vin Raja wrote:
> c
> >Exit code: 0

irb(main):003:0> m.each_with_index{|v,i| i}
=> ["a", "b", "c"]
irb(main):004:0> m.each_with_index{|v,i| p i}
0
1
2
=> ["a", "b", "c"]

The i variable in the block is indeed the index. But the result of the
entire
each_with_index expression is not the result of each block invocation,
but the collection
of all the array elements.

marcel
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-07-19 08:54
(Received via mailing list)
Alle giovedì 19 luglio 2007, Vin Raja ha scritto:
>
> and "each_with_index" seemed very obvious for the task but for the
> unexpected result.
>
> Raja

You're telling ruby to print the return value of each with index, which,
according to the ri documentation, is the array itself. If you want to
print
the different inidces, you need to put the call to puts inside the
block:

m.each_with_index{|v,i| puts( i )}

Putting i as the last statement of the block simply makes that the
return
value of the block, but this is ignored by each_with_index, so it's
useless.

I hope this helps

Stefano
41918fc34e4c3a365eabbd04ba9b551d?d=identicon&s=25 Vin Raja (vineetraja)
on 2007-07-19 09:12
Thanks All,

I got the nuance.

But my problem just got a bit more messier.
have a look down here:

r = ['KLP','OGN' ]
msg =<<MSG
  Found #{r.length} orders
  #{r.map.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }}
MSG

puts msg

This prints:

>ruby try.rb
(1)  KLP
(2)  OGN
  Found 2 orders
  KLPOGN

>Exit code: 0

And this time I also know why, thanks again.

But what I actually wanted was this sort of output:

>ruby try.rb

  Found 2 orders
  (1)  KLP
        (2)  OGN

>Exit code: 0

Any Help!

Thanks
raja
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-19 10:27
(Received via mailing list)
2007/7/19, Vin Raja <vineetraja@gmail.com>:
>   #{r.map.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }}
>   KLPOGN
>   (1)  KLP
>         (2)  OGN
>
> >Exit code: 0
>
> Any Help!

You are confusing string evaluation with output.  You need to remove
the puts from the string interpolation or use a different approach.
I'd keep things simple and do

r = ['KLP','OGN' ]
print "found ", r.size, " orders\n"
r.each_with_index do |e,i|
  print "  (", i+1, ") ", e, "\n"
end

robert
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-07-19 11:07
(Received via mailing list)
[mailto:list-bounce@example.com] On Behalf Of Vin Raja:
# But what I actually wanted was this sort of output:
# >ruby try.rb
#   Found 2 orders
#   (1)  KLP
#   (2)  OGN

just want you to show the evolution from your original scheme (spot the
difference) to that of roberts (retaining your original inlining)

C:\family\ruby>cat -n try.rb
     1  puts "---scheme 1---"
     2  r = ['KLP','OGN']
     3  msg =<<MSG
     4    #{puts "Found #{r.length} orders"}
     5    #{r.map.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }}
     6  MSG
     7  msg
     8
     9  puts "---scheme 2---"
    10  r = ['KLP','OGN']
    11  <<MSG
    12    #{puts "Found #{r.length} orders"}
    13    #{r.map.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }}
    14  MSG
    15
    16  puts "---scheme 3---"
    17  r = ['KLP','OGN']
    18  puts "Found #{r.length} orders"
    19  r.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }

C:\family\ruby>ruby try.rb
---scheme 1---
Found 2 orders
(1)  KLP
(2)  OGN
---scheme 2---
Found 2 orders
(1)  KLP
(2)  OGN
---scheme 3---
Found 2 orders
(1)  KLP
(2)  OGN

kind regards -botp
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-07-19 11:29
(Received via mailing list)
#... puts "(#{i+1})  #{v}\n" }

oops, lose "\n" pls.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-19 17:10
(Received via mailing list)
2007/7/19, Peña, Botp <botp@delmonte-phil.com>:
> #... puts "(#{i+1})  #{v}\n" }
>
> oops, lose "\n" pls.

It doesn't hurt though - output is the same.

robert
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-07-20 04:24
(Received via mailing list)
From: Robert Klemme [mailto:shortcutter@googlemail.com]
# 2007/7/19, Peña, Botp <botp@delmonte-phil.com>:
# > #... puts "(#{i+1})  #{v}\n" }
# > oops, lose "\n" pls.
#
# It doesn't hurt though - output is the same.

' just little concern for the op. he might assume puts requires \n.

but you're right, it does not hurt. he'll learn it later anyway...

kind regards -botp
41918fc34e4c3a365eabbd04ba9b551d?d=identicon&s=25 Vin Raja (vineetraja)
on 2007-07-20 07:42
Thanks All
It cleared up a lot of mess up at my head.

thanks again
-
Raja
8666d1ebabcea440585dfe831a4af9f1?d=identicon&s=25 Brian Adkins (Guest)
on 2007-07-20 16:31
(Received via mailing list)
On Jul 19, 3:12 am, Vin Raja <vineetr...@gmail.com> wrote:
> r = ['KLP','OGN' ]
> msg =<<MSG
>   Found #{r.length} orders
>   #{r.map.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }}
> MSG
>
> puts msg

It looks like others have already clarified things for you. This is a
bit of a tangent, but I just wanted to mention that 'map' is
superfluous in the above code i.e. the output is identical with and
without it.

irb(main):001:0> r = ['KLP','OGN' ]
=> ["KLP", "OGN"]
irb(main):002:0> r
=> ["KLP", "OGN"]
irb(main):003:0> r.map
=> ["KLP", "OGN"]
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2007-07-20 20:25
(Received via mailing list)
On 7/19/07, Marcel Molina Jr. <marcel@vernix.org> wrote:
> > b
>
> The i variable in the block is indeed the index. But the result of the entire
> each_with_index expression is not the result of each block invocation, but the 
collection
> of all the array elements.
>
> marcel
> --
> Marcel Molina Jr. <marcel@vernix.org>

Actually Enumerable#each_with_index appears to return  the receiver
object itself, identity is preserved.

irb(main):001:0> a = %w{a word array}
=> ["a", "word", "array"]
irb(main):002:0> a.equal?(a.each_with_index {|e, i| [e, i]})
=> true
irb(main):003:0> a = (1..3)
=> 1..3
irb(main):004:0> a.equal?(a.each_with_index {|e, i| [e, i]})
=> true

Although this is not documented, and could of course be overridden in
a class which includes enumerable or one of its subclasses.
--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
852a62a28f1de229dc861ce903b07a60?d=identicon&s=25 Phrogz (Guest)
on 2007-07-20 21:46
(Received via mailing list)
On Jul 19, 3:06 am, Peña, Botp <b...@delmonte-phil.com> wrote:
> 11  <<MSG
> 12    #{puts "Found #{r.length} orders"}
> 13    #{r.map.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }}
> 14  MSG
> 15
> 16  puts "---scheme 3---"
> 17  r = ['KLP','OGN']
> 18  puts "Found #{r.length} orders"
> 19  r.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }

One other variation which looks a little closer to what the OP wanted:

  module Enumerable
    def map_with_index
      idx = -1
      map{ |v| yield v,idx+=1 }
    end
  end

  puts "---scheme 4---"
  r = ['KLP','OGN']
  msg =<<ENDMSG
    Found #{r.length} orders
    #{r.map_with_index{ |v,i| "(#{i+1}) #{v}"}.join("\n")}
  ENDMSG
  puts msg
F62cfaca4a7a5bf58e08a664c2f41b94?d=identicon&s=25 Ian Whitlock (ian)
on 2007-07-20 23:01
Phrogz wrote:

>   puts "---scheme 4---"

While I have found the thread fascinating, it appears to me
that the original code and the 4 schemes are simply trying
to avoid the definition of a function.

def msg(r)
  puts "Found #{r.length} orders"
  r.each_with_index{|v,i|  puts "(#{i+1})  #{v}\n" }
end

x = ['KLP','OGN']
msg(x)

Can anyone explain what I am missing?

Thanks
Ian
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.