Array : each_with_index

V

Vin Raja

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
 
R

Robert Klemme

2007/7/19 said:
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.

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
 
M

Marcel Molina Jr.

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

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
 
S

Stefano Crocco

Alle gioved=C3=AC 19 luglio 2007, Vin Raja ha scritto:
Hi All,

I have following lines


m=3D['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

You're telling ruby to print the return value of each with index, which,=20
according to the ri documentation, is the array itself. If you want to prin=
t=20
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=20
value of the block, but this is ignored by each_with_index, so it's useless.

I hope this helps

Stefano
 
V

Vin Raja

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
 
R

Robert Klemme

2007/7/19 said:
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!

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
 
P

Peña, Botp

Iy4uLiBwdXRzICIoI3tpKzF9KSAgI3t2fVxuIiB9DQoNCm9vcHMsIGxvc2UgIlxuIiBwbHMuIA0K
DQo=
 
P

Peña, Botp

From: Robert Klemme [mailto:[email protected]]=20
# 2007/7/19, Pe=F1a, Botp <[email protected]>:
# > #... puts "(#{i+1}) #{v}\n" }
# > oops, lose "\n" pls.
#=20
# 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
 
B

Brian Adkins

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"]
 
R

Rick DeNatale

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

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

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

Phrogz

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" }

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
 
I

Ian Whitlock

Phrogz said:
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
 

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
474,262
Messages
2,571,311
Members
47,986
Latest member
ColbyG935

Latest Threads

Top