Array#each vs. Array#each_index iteration

hey folks,

  came across (what i consider) a strange difference between iterating
through an array with #each and #each_index - maybe someone can explain
this?

  i'm working on a baseball scorecard, that splits a string up into an
array, and then searches for keywords like "out," "single," "homer,"
etc. here's a simplified example that demonstrates what is confusing to
me:

···

#####
string = "Joe struck out looking blah blah Bill out at second blah blah"
array = string.split

array.each{|entry|
  p array.index(entry) if entry == "out"
}
puts
array.each_index{|index|
  p index if array[index] == "out"
}
#####

  i expected both ways of iterating through the array to give the same
results (2 and 7,) but they don't - what's returned is:

=> 2
=> 2

=> 2
=> 7

  why the heck does #each return 2 twice, instead of returning 2 and 7
like #each_index does? am i missing something obvious here? thanks in
advance for any help...

- j

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

hey folks,

  came across (what i consider) a strange difference between iterating
through an array with #each and #each_index - maybe someone can explain
this?

  i'm working on a baseball scorecard, that splits a string up into an
array, and then searches for keywords like "out," "single," "homer,"
etc. here's a simplified example that demonstrates what is confusing to
me:

#####
string = "Joe struck out looking blah blah Bill out at second blah blah"
array = string.split

array.each{|entry|
  p array.index(entry) if entry == "out"
}
puts
array.each_index{|index|
  p index if array[index] == "out"
}
#####

  i expected both ways of iterating through the array to give the same
results (2 and 7,) but they don't - what's returned is:

=> 2
=> 2

=> 2
=> 7

  why the heck does #each return 2 twice, instead of returning 2 and 7
like #each_index does?

Because Array#index returns the index of the first occurrence of the argument,
that is always 2, regardless of the iteration. In other words, Array#index is
not suitable to be used from within each to access the index of the current
element. If you need both the index and the element, you can use
Array#each_with_index which passes both the element and its index to the
block.

am i missing something obvious here? thanks in
advance for any help...

- j

I hope this helps

Stefano

···

On Sunday 17 July 2011 23:10:23 jake kaiden wrote:

The documentation clearly says that index method will return the index of
the first match so it's not an issue with each, it's the way index method
has been designed to work.

http://ruby-doc.org/core/classes/Array.html#M000237

Thanks,
Mayank Kohaley

···

On Sun, Jul 17, 2011 at 7:40 PM, jake kaiden <jakekaiden@yahoo.com> wrote:

hey folks,

came across (what i consider) a strange difference between iterating
through an array with #each and #each_index - maybe someone can explain
this?

i'm working on a baseball scorecard, that splits a string up into an
array, and then searches for keywords like "out," "single," "homer,"
etc. here's a simplified example that demonstrates what is confusing to
me:

#####
string = "Joe struck out looking blah blah Bill out at second blah blah"
array = string.split

array.each{|entry|
p array.index(entry) if entry == "out"
}
puts
array.each_index{|index|
p index if array[index] == "out"
}
#####

i expected both ways of iterating through the array to give the same
results (2 and 7,) but they don't - what's returned is:

=> 2
=> 2

=> 2
=> 7

why the heck does #each return 2 twice, instead of returning 2 and 7
like #each_index does? am i missing something obvious here? thanks in
advance for any help...

- j

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

i was indeed missing something obvious - thanks for pointing it out!
somehow i overlooked that Array#index was always going to return the
first occurrence even if it was within an iteration...

  thanks again - the scorecard is coming along - go sox!

···

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

[snip]

i overlooked that Array#index was always going to return the
first occurrence even if it was within an iteration...

[snip]

Be careful not to think that a method *knows* that it's being used in the context of an iteration, even if it's a method of the same object you're iterating.

···

On 7/17/11 5:03 PM, jake kaiden wrote:

--
Stefano Mioli

Have you been referred to #each_with_index already?

array.each{|entry, index|
p index if entry == "out"
}

This is more efficient also since #index has to search the Array from
the beginning.

Kind regards

robert

···

On Sun, Jul 17, 2011 at 5:03 PM, jake kaiden <jakekaiden@yahoo.com> wrote:

i was indeed missing something obvious - thanks for pointing it out!
somehow i overlooked that Array#index was always going to return the
first occurrence even if it was within an iteration...

thanks again - the scorecard is coming along - go sox!

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Have you been referred to #each_with_index already?

Do you mean Array#each_index ?

array.each{|entry, index|
  p index if entry == "out"
}

Because in the example you still used "each" :slight_smile:

Somehow I did know about that behavior of Array#each_index but yet I couldn't find it on class Array - RDoc Documentation .

I don't know, I can't stop my habit of using ruby-doc.org as my #1 source although it falls short every now and then. I've been pointed to other sites already but come back to this one always, it feels somehow "official" although my understanding is it isn't (and that there is none).

Something I think the PHP and Python projects got better ... arrrrr, offtopic.

- Markus

···

On 18.07.2011 13:05, Robert Klemme wrote:

My bad. No, I meant #each_with_index.

array.each_with_index do |entry, index|
  p index if entry == "out"
end

Kind regards

robert

···

On Mon, Jul 18, 2011 at 1:19 PM, Markus Fischer <markus@fischer.name> wrote:

On 18.07.2011 13:05, Robert Klemme wrote:

Have you been referred to #each_with_index already?

Do you mean Array#each_index ?

array.each{|entry, index|
p index if entry == "out"
}

Because in the example you still used "each" :slight_smile:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Array#each_index is definitely there:
http://ruby-doc.org/core/classes/Array.html#M000232

For the other #each methods you may have to look at the Enumerable
module which Array mixes in:
http://ruby-doc.org/core/classes/Enumerable.html

Vale,
Marvin

···

Am 18.07.2011 13:19, schrieb Markus Fischer:

On 18.07.2011 13:05, Robert Klemme wrote:

Have you been referred to #each_with_index already?

Do you mean Array#each_index ?

array.each{|entry, index| p index if entry == "out" }

Because in the example you still used "each" :slight_smile:

Somehow I did know about that behavior of Array#each_index but yet I
couldn't find it on http://www.ruby-doc.org/core/classes/Array.html
.

I don't know, I can't stop my habit of using ruby-doc.org as my #1
source although it falls short every now and then. I've been pointed
to other sites already but come back to this one always, it feels
somehow "official" although my understanding is it isn't (and that
there is none).