# Iterating methods on multiple parameters

**URL:** <https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107>\
**Category:** Ruby\
**Created:** [September 20, 2008, 5:53pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107 "2008-09-20T17:53:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 20, 2008, 5:53pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/1 "2008-09-20T17:53:15Z")

</div>

I’m thinking there must be a great Ruby-way to do the same thing to many  
different variables. Here is a boiled down version of what I have:

```
    @yn = Unit.new("#{@yn} feet")
    @yc = Unit.new("#{yc} feet")
    @v = Unit.new("#{@v} fps")
    @twmax = Unit.new("#{@twmax} lbs/ft^2")
    @tc = Unit.new("#{@tc} lbs/ft^2")
    @twc = Unit.new("#{@twc} lbs/ft^2")

```

My first thought is to create a hash of variables like this:

```
    results = {'yn' => "#{@yn} feet", 'yc' => "#{yc} feet", 'v' =>

```

“#{@v} fps”, ‘twmax’ =\> “#{twmax} lbs/ft^2”, ‘tc’ =\> “#{tc} lbs/ft^2”,  
‘twc’ =\> “#{twc} lbs/ft^2”}

then use a block something like this?

```
    results.each_value {|item| Unit.new(item)}

```

…but that doesn’t seem to work. Any ideas to make this better?

Thank you!

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 20, 2008, 6:07pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/2 "2008-09-20T18:07:47Z")

</div>

Jason L. wrote:

> I’m thinking there must be a great Ruby-way to do the same thing to many  
> different variables. Here is a boiled down version of what I have:
> 
> ```
> @yn = Unit.new("#{@yn} feet")
> @yc = Unit.new("#{yc} feet")
> @v = Unit.new("#{@v} fps")
> @twmax = Unit.new("#{@twmax} lbs/ft^2")
> @tc = Unit.new("#{@tc} lbs/ft^2")
> @twc = Unit.new("#{@twc} lbs/ft^2")
> 
> ```
> 
> My first thought is to create a hash of variables like this:
> 
> ```
> results = {'yn' => "#{@yn} feet", 'yc' => "#{yc} feet", 'v' =>
> 
> ```
> 
> “#{@v} fps”, ‘twmax’ =\> “#{twmax} lbs/ft^2”, ‘tc’ =\> “#{tc} lbs/ft^2”,  
> ‘twc’ =\> “#{twc} lbs/ft^2”}
> 
> then use a block something like this?
> 
> ```
> results.each_value {|item| Unit.new(item)}
> 
> ```
> 
> …but that doesn’t seem to work. Any ideas to make this better?
> 
> Thank you!

The most hardcore way:

h={:yn=\>“feet”,:yc=\>“feet”,…}  
h.each\_pair  
{ |v,u|  
iv=:"@#{v}"  
instance\_variable\_set(iv,Unit::new("#{instance\_variable\_get(iv)} #{u}"))  
}

Or there are some variations using eval, but I think using eval is less  
elegant.

TPR.

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 12:32am UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/3 "2008-09-21T00:32:21Z")

</div>

Thank you.

But I think my problem is simpler than that. I didn’t explain well  
enough.

I’m finding that with either each\_pair or each\_value, I can’t get what I  
need.

here is a simple case:

h = {‘x’=\>2, ‘y’=\>5}

I want to change the values of the hash and assign those to new hash:

i = h.each\_value {|v| v \* 2}

I wanted i =\> {‘x’=\>4, ‘y’=\>10} but it remains i =\> {‘x’=\>2, ‘y’=\>5}

Is there some form of a ‘collect’ method for hashes - similar to array?  
There must be some other easy answer.

thank you!

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 2:07am UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/4 "2008-09-21T02:07:30Z")

</div>

I just saw a similar issue (#163350 of this forum).

seems like this might work to change values of a hash:

hash = {‘x’=\>2, ‘y’=5}  
hash\_new = hash.inject({}) do |h, (k,v)|  
h[v \* 2] = k  
h  
end

although this returns {10=\>“y”, 4=\>“x”}

something seems amiss…

what do you think?

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 9:56pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/5 "2008-09-21T21:56:58Z")

</div>

Jason L. wrote:

> I just saw a similar issue (#163350 of this forum).
> 
> seems like this might work to change values of a hash:
> 
> hash = {‘x’=\>2, ‘y’=5}  
> hash\_new = hash.inject({}) do |h, (k,v)|  
> h[v \* 2] = k  
> h  
> end
> 
> although this returns {10=\>“y”, 4=\>“x”}
> 
> something seems amiss…

hash = {‘x’=\>2, ‘y’=\>5}  
hash\_new = hash.inject({}) do |h, (k,v)|  
h[k] = v \* 2  
h  
end

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 10:05pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/6 "2008-09-21T22:05:52Z")

</div>

Thanks everyone!

Is there a reason the hsh.inject method is not included in the Ruby  
documentation?

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 5:32am UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/7 "2008-09-21T05:32:42Z")

</div>

On Sat, Sep 20, 2008 at 6:59 PM, Jason L.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> although this returns {10=\>“y”, 4=\>“x”}  
> With your example…

h = Hash[‘x’, 2, ‘y’, 5]  
h.each\_key {|k| h[k] \*= 2}

Todd

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 11:28pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/8 "2008-09-21T23:28:27Z")

</div>

You can see I don’t know very much about this language. I’ve been trying  
really hard to learn!

I was looking in [RDoc Documentation](http://www.ruby-doc.org/core/)

and just went to Class Hash and didn’t see that method. I didn’t think  
of Enumerable. I originally thought the collect method would work  
similar to arrays and noticed in Google searching someone said Hashes  
don’t have collect. So then I just assumed Hashes must also be missing  
inject as well.

Thanks for your time.

---

<div class="post-metadata">

**Author:** ![leveille](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a88e57/32.png) [@leveille](https://www.ruby-forum.com/u/leveille)\
**Post date:** [September 21, 2008, 10:36pm UTC](https://www.ruby-forum.com/t/iterating-methods-on-multiple-parameters/149107/9 "2008-09-21T22:36:38Z")

</div>

On Sep 21, 2008, at 3:57 PM, Jason L. wrote:

> Thanks everyone!
> 
> Is there a reason the hsh.inject method is not included in the Ruby  
> documentation?

Sure it is. In my Programming Ruby, 2 ed., on page 492 it say that  
Hash mixes in the Enumerable module and lists inject as one of the  
methods. Enumerable#inject itself is documented on page 456.

Depending on where/how you’re looking, it is!

$ ri Hash#inject  
Nothing known about Hash#inject

## $ fri Hash#inject ------------------------------------------------------ Enumerable#inject enum.inject(initial) {| memo, obj | block } =\> obj enum.inject {| memo, obj | block } =\> obj

```
  Combines the elements of enum by applying the block to an
  accumulator value (memo) and each element in turn. At each step,
  memo is set to the value returned by the block. The first form
  lets you supply an initial value for memo. The second form uses
  the first element of the collection as a the initial value (and
  skips that element while iterating).

     # Sum some numbers
     (5..10).inject {|sum, n| sum + n } #=> 45
     # Multiply some numbers
     (5..10).inject(1) {|product, n| product * n } #=> 151200

     # find the longest word
     longest = %w{ cat sheep bear }.inject do |memo,word|
        memo.length > word.length ? memo : word
     end
     longest #=> "sheep"

     # find the length of the longest word
     longest = %w{ cat sheep bear }.inject(0) do |memo,word|
        memo >= word.length ? memo : word.length
     end
     longest #=> 5

```

What leads you to think that it isn’t documented?

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid
