# Hash#shift

**URL:** <https://www.ruby-forum.com/t/hash-shift/104118>\
**Category:** Ruby\
**Created:** [May 14, 2007, 3:00pm UTC](https://www.ruby-forum.com/t/hash-shift/104118 "2007-05-14T15:00:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![duffbeer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ec9cab/32.png) [@duffbeer](https://www.ruby-forum.com/u/duffbeer)\
**Post date:** [May 14, 2007, 3:00pm UTC](https://www.ruby-forum.com/t/hash-shift/104118/1 "2007-05-14T15:00:11Z")

</div>

Hi,

I was reading this  
[http://www.rubycentral.com/book/ref\_c\_hash.html#Hash.shift](http://www.rubycentral.com/book/ref_c_hash.html#Hash.shift)

and I wondered how this could be useful. I must be missing something.

I tried this

ahash = {“a” =\> “apple”,“b”=\> “boat”,“c” =\>“car”, “dog” =\> “zebra”,  
“elephant” =\> “yak”}  
p ahash #=\>{“a” =\> “apple”,“b”=\> “boat”,“c” =\>“car”,“elephant” =\>  
“yak”, “dog” =\> “zebra”}  
p ahash.shift #=\>[“a”, “apple”]  
p ahash.shift #=\>[“b”, “boat”]  
p ahash.shift #=\>[“c”, “car”]  
p ahash.shift #=\>[“elephant”, “yak”]  
p ahash.shift #=\>[“dog”, “zebra”]

Since the order of a hash is not guaranteed, you do not know what you  
are shifting at any given time. Is this right?  
If you just wanted to shift everything you could use Hash#each.

What am I missing?

Harry

–

A Look into Japanese Ruby List in English  
[http://www.kakueki.com/](http://www.kakueki.com/)

---

<div class="post-metadata">

**Author:** ![duffbeer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ec9cab/32.png) [@duffbeer](https://www.ruby-forum.com/u/duffbeer)\
**Post date:** [May 14, 2007, 3:22pm UTC](https://www.ruby-forum.com/t/hash-shift/104118/2 "2007-05-14T15:22:15Z")

</div>

On 14.05.2007 14:59, Harry K. wrote:

> “elephant” =\> “yak”}  
> If you just wanted to shift everything you could use Hash#each.
> 
> What am I missing?

I never had use for this myself but it might be useful in cases where  
you want to iterate through a (possibly temporary) Hash and make sure  
that elements that you have processed are removed. Like

> > h={:foo=\>1, :bar=\>2, :baz=\>3}  
> > =\> {:baz=\>3, :foo=\>1, :bar=\>2}
> 
> > until h.empty?  
> > k, v = h.shift  
> > puts “processing: #{k} - #{v}”  
> > end  
> > processing: baz - 3  
> > processing: foo - 1  
> > processing: bar - 2  
> > =\> nil
> 
> > h  
> > =\> {}

If you now leave the loop early (for whatever reasons, “return” or  
raise) you only leave elements that still have to be processed in the  
Hash.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![duffbeer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ec9cab/32.png) [@duffbeer](https://www.ruby-forum.com/u/duffbeer)\
**Post date:** [May 14, 2007, 4:03pm UTC](https://www.ruby-forum.com/t/hash-shift/104118/3 "2007-05-14T16:03:20Z")

</div>

On 5/14/07, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> processing: baz - 3
> 
> ```
> robert
> 
> ```

OK.  
You would be shifting in a somewhat random order but you would be able  
to keep track of what had not yet been shifted.

Thanks for that example.

Harry

–

A Look into Japanese Ruby List in English  
[http://www.kakueki.com/](http://www.kakueki.com/)
