# Hashes and Enumerable#each\_with\_index

**URL:** <https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765>\
**Category:** ruby-talk\
**Created:** [24 April 2003 22:26 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765 "2003-04-24T22:26:01Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ryan\_Pavlik1](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@Ryan\_Pavlik1](https://rubytalk.org/u/Ryan_Pavlik1)\
**Post date:** [24 April 2003 22:26 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/1 "2003-04-24T22:26:01Z")

</div>

OK, looking at the archives I know this was discussed a few years ago,  
but there seems to be no real conclusion or improvement since then.

The problem: Hash#each\_with\_index returns an index that is not usable  
to address the hash. That is, given the following:

```
h = Hash.new
h.each_with_index {
    > o, i |
    ...
}

```

i is not defined such that h[i] == o, which is both misleading and  
seemingly useless. (This behavior, as per the previous discussion, can  
be achieved with h.to\_a.each\_with\_index.)

Would it not be more useful to adopt the definiton of  
Enumerable#each\_with\_index where the index given is such that e[i] == o  
for any given Enumerable?

A specific example of where this is useful is in my current codebase,  
where I add \_pre\_store to Enumerable, for Marshalling objects. This  
walks through (using each\_with\_index) the Enumerable, replacing indices  
that refer to persistant objects with temporary references, to be  
restored on load.

Given the current definition, which returns only numeric indices, this  
makes any Enumerable subclass that does not use numeric indices not  
follow this pattern, thus requiring specific coding. This seems like a  
waste. Enumerable provides no other interface for obtaining addressable  
indices.

Since containers like this all mixin Enumerable, it would seem that  
using this definition would be much more accurate and useful… or at  
least _some_ interface in Enumerable that acted this way, such as  
each\_index.

> **···**
>
> –  
> Ryan Pavlik [rpav@users.sf.net](mailto:rpav@users.sf.net)
> 
> “Now is not the time for sarcasm! Now is the time  
> for nefarious action.” - 8BT

---

<div class="post-metadata">

**Author:** ![David\_A\_Black2](https://avatars.discourse-cdn.com/v4/letter/d/57b2e6/32.png) [@David\_A\_Black2](https://rubytalk.org/u/David_A_Black2)\
**Post date:** [24 April 2003 22:40 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/2 "2003-04-24T22:40:47Z")

</div>

Hi –

> OK, looking at the archives I know this was discussed a few years ago,  
> but there seems to be no real conclusion or improvement since then.
> 
> The problem: Hash#each\_with\_index returns an index that is not usable  
> to address the hash. That is, given the following:
> 
> ```
> h = Hash.new
> h.each_with_index {
> > o, i |
> ...
> }
> 
> ```
> 
> i is not defined such that h[i] == o, which is both misleading and  
> seemingly useless. (This behavior, as per the previous discussion, can  
> be achieved with h.to\_a.each\_with\_index.)
> 
> Would it not be more useful to adopt the definiton of  
> Enumerable#each\_with\_index where the index given is such that e[i] == o  
> for any given Enumerable?

One problem I see is: how could you implement this, in Enumerable, in  
terms of #each?

The current #each\_with\_index is essentially:

i = 0  
each {|e| yield(e,i); i += 1}

If the new method (which I think should have a new name 🙂 did the  
above for arrays, but did this for hashes:

each {|k,v| yield(v,k)}

you’d be thrown back on defining something differently for different  
classes that mixed in Enumerable.

David

> **···**
>
> On Fri, 25 Apr 2003, Ryan Pavlik wrote:
> 
> –  
> David Alan Black  
> home: [dblack@superlink.net](mailto:dblack@superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [24 April 2003 23:10 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/3 "2003-04-24T23:10:04Z")

</div>

Hi,

> **···**
>
> In message “Hashes and Enumerable#each\_with\_index” on 03/04/25, Ryan Pavlik [rpav@nwlink.com](mailto:rpav@nwlink.com) writes:
> 
> > The problem: Hash#each\_with\_index returns an index that is not usable  
> > to address the hash. That is, given the following:
> > 
> > h = Hash.new  
> > h.each\_with\_index {  
> > \> o, i |  
> > …  
> > }
> > 
> > i is not defined such that h[i] == o, which is both misleading and  
> > seemingly useless. (This behavior, as per the previous discussion, can  
> > be achieved with h.to\_a.each\_with\_index.)
> > 
> > Would it not be more useful to adopt the definiton of  
> > Enumerable#each\_with\_index where the index given is such that e[i] == o  
> > for any given Enumerable?
> 
> No. Index in each\_with\_index means offset of the values. It might be  
> possible to implement a method that you described for arrays, hashes,  
> string, etc. But it should have different name.
> 
> ```
> matz.
> 
> ```

---

<div class="post-metadata">

**Author:** ![Berger\_Daniel2](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@Berger\_Daniel2](https://rubytalk.org/u/Berger_Daniel2)\
**Post date:** [24 April 2003 23:20 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/4 "2003-04-24T23:20:08Z")

</div>

Ryan Pavlik wrote:

> OK, looking at the archives I know this was discussed a few years ago,  
> but there seems to be no real conclusion or improvement since then.
> 
> The problem: Hash#each\_with\_index returns an index that is not usable  
> to address the hash. That is, given the following:
> 
> ```
> h = Hash.new
> h.each_with_index {
> > o, i |
> ...
> }
> 
> ```
> 
> i is not defined such that h[i] == o, which is both misleading and  
> seemingly useless. (This behavior, as per the previous discussion, can  
> be achieved with h.to\_a.each\_with\_index.)
> 
> Would it not be more useful to adopt the definiton of  
> Enumerable#each\_with\_index where the index given is such that e[i] == o  
> for any given Enumerable?

This operation seems most sensical, to me, when used with ordered  
hashes. Here’s a patch for Gotoken’s “pseudohash” package on the RAA:

# add to pseudohash.rb (not heavily tested)

def   
if k.kind\_of?(Fixnum)  
key = order[k]  
return self.fetch(key)  
else  
return super  
end  
end

def each\_with\_index  
rest = keys - order  
order.each{|k,v| yield(k,self[k],order.index(k)) if include?(k)}  
rest.each{|k,v| yield(k,self[k],order.index(k)) }  
end

example:

record = PseudoHash.new.with\_order [‘Alice’, ‘Bob’, ‘Charlee’]  
record[‘Charlee’] = 90  
record[‘Alice’] = 91  
record[‘Bob’] = 89  
record.each\_with\_index{|k,v,i|  
puts “Key: #{k}”  
puts “Index: #{i}”  
puts "Using index: " + record[i].to\_s  
puts "Using key: " + record[k].to\_s  
puts “=” \* 10  
}

Regards,

Dan

a = [74, 117, 115, 116, 32, 65, 110, 111, 116, 104, 101, 114, 32, 82]  
a.push(117,98, 121, 32, 72, 97, 99, 107, 101, 114)  
puts a.pack(“C\*”)

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [25 April 2003 07:25 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/5 "2003-04-25T07:25:52Z")

</div>

Or indeed just ‘h.each’ (if you replace |o,i| with |i,o|)

It did seem a bit strange to me at first that the methods don’t really line  
up:

```
Array#each <=> Hash#each_value
Array#each_with_index <=> Hash#each (but with args reversed)

```

Regards,

Brian.

> **···**
>
> On Fri, Apr 25, 2003 at 07:26:01AM +0900, Ryan Pavlik wrote:
> 
> > OK, looking at the archives I know this was discussed a few years ago,  
> > but there seems to be no real conclusion or improvement since then.
> > 
> > The problem: Hash#each\_with\_index returns an index that is not usable  
> > to address the hash. That is, given the following:
> > 
> > ```
> > h = Hash.new
> > h.each_with_index {
> > > o, i |
> > ...
> > }
> > 
> > ```
> > 
> > i is not defined such that h[i] == o, which is both misleading and  
> > seemingly useless. (This behavior, as per the previous discussion, can  
> > be achieved with h.to\_a.each\_with\_index.)

---

<div class="post-metadata">

**Author:** ![Sam\_Roberts1](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@Sam\_Roberts1](https://rubytalk.org/u/Sam_Roberts1)\
**Post date:** [26 April 2003 16:31 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/6 "2003-04-26T16:31:45Z")

</div>

Quoteing [rpav@nwlink.com](mailto:rpav@nwlink.com), on Fri, Apr 25, 2003 at 07:26:01AM +0900:

> OK, looking at the archives I know this was discussed a few years ago,  
> but there seems to be no real conclusion or improvement since then.
> 
> The problem: Hash#each\_with\_index returns an index that is not usable  
> to address the hash. That is, given the following:
> 
> ```
> h = Hash.new
> h.each_with_index {
> > o, i |
> ...
> }
> 
> ```
> 
> i is not defined such that h[i] == o, which is both misleading and  
> seemingly useless. (This behavior, as per the previous discussion, can  
> be achieved with h.to\_a.each\_with\_index.)

This function already exists, for a Hash its called Hash#each.

I guess Hash could override the each\_with\_index it gets from enumerable,  
aliasing it to each, but that seems like it would be LESS useful, not  
more useful.

Sam

---

<div class="post-metadata">

**Author:** ![HAL\_9000](https://avatars.discourse-cdn.com/v4/letter/h/90ced4/32.png) [@HAL\_9000](https://rubytalk.org/u/HAL_9000)\
**Post date:** [25 April 2003 01:01 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/7 "2003-04-25T01:01:43Z")

</div>

> > Would it not be more useful to adopt the definiton of  
> > Enumerable#each\_with\_index where the index given is such that e[i] == o  
> > for any given Enumerable?

Hmm, not a good idea in general, I think.  
But you could always make ‘each\_with\_key’  
which would work that way, while leaving  
each\_with\_index as Matz designed (and  
likes) it, and as we are used to it.

Hal

---

<div class="post-metadata">

**Author:** ![Ryan\_Pavlik1](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@Ryan\_Pavlik1](https://rubytalk.org/u/Ryan_Pavlik1)\
**Post date:** [25 April 2003 06:00 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/8 "2003-04-25T06:00:24Z")

</div>

> Hi –

\> \> Would it not be more useful to adopt the definiton of \> \> Enumerable#each\_with\_index where the index given is such that e[i] == o \> \> for any given Enumerable? \> \> One problem I see is: how could you implement this, in Enumerable, in \> terms of #each? \> 

I don’t see why there must exist a default implementation in  
Enumerable… this is a good example of why. I personally have no  
preference as to whether it has a new name or not, but I’m guessing  
there’s little choice since likely a good deal of code already exists  
that relies on the current behavior.

> **···**
>
> On Fri, 25 Apr 2003 07:40:47 +0900 [dblack@superlink.net](mailto:dblack@superlink.net) wrote:
> 
> > On Fri, 25 Apr 2003, Ryan Pavlik wrote:
> 
> –  
> Ryan Pavlik [rpav@users.sf.net](mailto:rpav@users.sf.net)
> 
> “Now is not the time for sarcasm! Now is the time  
> for nefarious action.” - 8BT

---

<div class="post-metadata">

**Author:** ![Ryan\_Pavlik1](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@Ryan\_Pavlik1](https://rubytalk.org/u/Ryan_Pavlik1)\
**Post date:** [25 April 2003 06:03 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/9 "2003-04-25T06:03:29Z")

</div>

> Hi,

\> \>Would it not be more useful to adopt the definiton of \> \>Enumerable#each\_with\_index where the index given is such that e[i] == o \> \>for any given Enumerable? \> \> No. Index in each\_with\_index means offset of the values. It might be \> possible to implement a method that you described for arrays, hashes, \> string, etc. But it should have different name.

I actually don’t really care here… new name (the each\_with\_key  
suggestion sounds OK to me) or old name, as long as it’s there, it’d be  
a little more useful, IMHO.

> **···**
>
> On Fri, 25 Apr 2003 08:10:04 +0900 [matz@ruby-lang.org](mailto:matz@ruby-lang.org) (Yukihiro Matsumoto) wrote:
> 
> > In message “Hashes and Enumerable#each\_with\_index” \> on 03/04/25, Ryan Pavlik [rpav@nwlink.com](mailto:rpav@nwlink.com) writes:
> 
> –  
> Ryan Pavlik [rpav@users.sf.net](mailto:rpav@users.sf.net)
> 
> “Now is not the time for sarcasm! Now is the time  
> for nefarious action.” - 8BT

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [25 April 2003 06:25 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/10 "2003-04-25T06:25:14Z")

</div>

Hi,

> > No. Index in each\_with\_index means offset of the values. It might be  
> > possible to implement a method that you described for arrays, hashes,  
> > string, etc. But it should have different name.
> 
> I actually don’t really care here… new name (the each\_with\_key  
> suggestion sounds OK to me) or old name, as long as it’s there, it’d be  
> a little more useful, IMHO.

I’m positive. But describe what you want more precisely. The  
following behavior OK for you?

Suppose it is called “each\_with\_foo”:

```
* each_with_foo should be available for all built-in classes that
  have obj[x] access.

* each_with_foo must give (x,y) that obj[y] == x be true always.

```

Replace “foo” with the right word. I don’t think it’s “key”, since  
Array index is not key after all.

```
						matz.

```

> **···**
>
> In message “Re: Hashes and Enumerable#each\_with\_index” on 03/04/25, Ryan Pavlik [rpav@nwlink.com](mailto:rpav@nwlink.com) writes:

---

<div class="post-metadata">

**Author:** ![David\_A\_Black2](https://avatars.discourse-cdn.com/v4/letter/d/57b2e6/32.png) [@David\_A\_Black2](https://rubytalk.org/u/David_A_Black2)\
**Post date:** [25 April 2003 10:35 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/11 "2003-04-25T10:35:41Z")

</div>

Hi –

> **···**
>
> On Fri, 25 Apr 2003, Ryan Pavlik wrote:
> 
> > On Fri, 25 Apr 2003 07:40:47 +0900 \> [dblack@superlink.net](mailto:dblack@superlink.net) wrote:
> > 
> > > Hi –
> > > 
> > > On Fri, 25 Apr 2003, Ryan Pavlik wrote:
> > 
> > \> \> Would it not be more useful to adopt the definiton of \> \> Enumerable#each\_with\_index where the index given is such that e[i] == o \> \> for any given Enumerable? \> \> One problem I see is: how could you implement this, in Enumerable, in \> terms of #each? \>
> > 
> > I don’t see why there must exist a default implementation in  
> > Enumerable… this is a good example of why. I personally have no  
> > preference as to whether it has a new name or not, but I’m guessing  
> > there’s little choice since likely a good deal of code already exists  
> > that relies on the current behavior.
> 
> If it applies to “any given Enumerable”, then presumably it’s defined  
> in Enumerable 🙂
> 
> David
> 
> –  
> David Alan Black  
> home: [dblack@superlink.net](mailto:dblack@superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![Ryan\_Pavlik1](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@Ryan\_Pavlik1](https://rubytalk.org/u/Ryan_Pavlik1)\
**Post date:** [25 April 2003 06:41 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/12 "2003-04-25T06:41:59Z")

</div>

\> I'm positive. But describe what you want more precisely. The \> following behavior OK for you? \> \> Suppose it is called "each\_with\_foo": \> \> \* each\_with\_foo should be available for all built-in classes that \> have obj[x] access. \> \> \* each\_with\_foo must give (x,y) that obj[y] == x be true always. \> \> Replace "foo" with the right word. I don't think it's "key", since \> Array index is not key after all.

David Black (iirc) had a good suggestion on #ruby-lang, and that was  
"each\_pair".

> **···**
>
> On Fri, 25 Apr 2003 15:25:14 +0900 [matz@ruby-lang.org](mailto:matz@ruby-lang.org) (Yukihiro Matsumoto) wrote:
> 
> –  
> Ryan Pavlik [rpav@users.sf.net](mailto:rpav@users.sf.net)
> 
> “Now is not the time for sarcasm! Now is the time  
> for nefarious action.” - 8BT

---

<div class="post-metadata">

**Author:** ![Dave\_Mail\_Archive](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@Dave\_Mail\_Archive](https://rubytalk.org/u/Dave_Mail_Archive)\
**Post date:** [25 April 2003 06:55 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/13 "2003-04-25T06:55:06Z")

</div>

Yukihiro Matsumoto wrote:

> ```
> * each_with_foo should be available for all built-in classes that
> have obj[x] access.
> 
> * each_with_foo must give (x,y) that obj[y] == x be true always.
> 
> ```
> 
> Replace “foo” with the right word. I don’t think it’s “key”, since  
> Array index is not key after all.

Or, have each class that wants to support this protocol define a method  
‘each\_foo’. Then have enumerable implement ‘each\_with\_foo’ as

module Enumerable  
def each\_with\_foo  
each\_foo {|foo| yield self[foo], foo}  
end  
end

Then the change to Hash is simply

alias each\_foo each\_key

and to array

alias each\_foo each\_index

However, how often to you want to do an each\_with\_index polymorphically?

Cheers

Dave

---

<div class="post-metadata">

**Author:** ![David\_A\_Black2](https://avatars.discourse-cdn.com/v4/letter/d/57b2e6/32.png) [@David\_A\_Black2](https://rubytalk.org/u/David_A_Black2)\
**Post date:** [25 April 2003 10:31 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/14 "2003-04-25T10:31:43Z")

</div>

Hi –

> **···**
>
> On Fri, 25 Apr 2003, Ryan Pavlik wrote:
> 
> > On Fri, 25 Apr 2003 15:25:14 +0900 \> [matz@ruby-lang.org](mailto:matz@ruby-lang.org) (Yukihiro Matsumoto) wrote:
> > 
> > \> I'm positive. But describe what you want more precisely. The \> following behavior OK for you? \> \> Suppose it is called "each\_with\_foo": \> \> \* each\_with\_foo should be available for all built-in classes that \> have obj[x] access. \> \> \* each\_with\_foo must give (x,y) that obj[y] == x be true always. \> \> Replace "foo" with the right word. I don't think it's "key", since \> Array index is not key after all.
> > 
> > David Black (iirc) had a good suggestion on #ruby-lang, and that was  
> > “each\_pair”.
> 
> It was flgr – not sure who that is though.
> 
> David
> 
> –  
> David Alan Black  
> home: [dblack@superlink.net](mailto:dblack@superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![Ryan\_Pavlik1](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@Ryan\_Pavlik1](https://rubytalk.org/u/Ryan_Pavlik1)\
**Post date:** [25 April 2003 17:27 UTC](https://rubytalk.org/t/hashes-and-enumerable-each-with-index/5765/15 "2003-04-25T17:27:26Z")

</div>

\> Or, have each class that wants to support this protocol define a method \> 'each\_foo'. Then have enumerable implement 'each\_with\_foo' as \> \> module Enumerable \> def each\_with\_foo \> each\_foo {|foo| yield self[foo], foo} \> end \> end

This is perhaps an OK default, but it would be nice to see a O(1)  
iterator for Hash eventually. 😉

 \> However, how often to you want to do an each\_with\_index polymorphically?

This is the point of the addition—I want to access every Enumerable  
from Enumerable, to be able to replace and restore references to  
Marshalled objects (so other objects stored with an OID don’t get  
cloned by the store/load). It’s better to do this once in Enumerable  
than for every class individually.

There are, I’m sure, a myriad of uses for e[k] == i, though. Not having  
to look up the method for every class ought to be one. 😉

> **···**
>
> On Fri, 25 Apr 2003 15:55:06 +0900 Dave Thomas [dave@pragprog.com](mailto:dave@pragprog.com) wrote:
> 
> –  
> Ryan Pavlik [rpav@users.sf.net](mailto:rpav@users.sf.net)
> 
> “These monkeys of which you speak… are they mentally  
> deficient by human or monkey standards?” - 8BT
