iterating methods on multiple parameters

Discussion in 'Ruby' started by Jason Lillywhite, Sep 20, 2008.

  1. 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!
    --
    Posted via http://www.ruby-forum.com/.
    Jason Lillywhite, Sep 20, 2008
    #1
    1. Advertising

  2. Jason Lillywhite

    Thomas B. Guest

    Jason Lillywhite 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.
    --
    Posted via http://www.ruby-forum.com/.
    Thomas B., Sep 20, 2008
    #2
    1. Advertising

  3. 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!
    --
    Posted via http://www.ruby-forum.com/.
    Jason Lillywhite, Sep 20, 2008
    #3
  4. 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?
    --
    Posted via http://www.ruby-forum.com/.
    Jason Lillywhite, Sep 21, 2008
    #4
  5. Jason Lillywhite

    Todd Benson Guest

    On Sat, Sep 20, 2008 at 6:59 PM, Jason Lillywhite
    <> 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"}


    With your example...

    h = Hash['x', 2, 'y', 5]
    h.each_key {|k| h[k] *= 2}

    Todd
    Todd Benson, Sep 21, 2008
    #5
  6. Jason Lillywhite 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
    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Sep 21, 2008
    #6
  7. Thanks everyone!

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



    --
    Posted via http://www.ruby-forum.com/.
    Jason Lillywhite, Sep 21, 2008
    #7
  8. On Sep 21, 2008, at 3:57 PM, Jason Lillywhite 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 Biedenharn http://agileconsultingllc.com
    Rob Biedenharn, Sep 21, 2008
    #8
  9. You can see I don't know very much about this language. I've been trying
    really hard to learn!

    I was looking in 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.
    --
    Posted via http://www.ruby-forum.com/.
    Jason Lillywhite, Sep 21, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jonck van der Kogel
    Replies:
    2
    Views:
    978
    Jonck van der Kogel
    May 27, 2004
  2. carl
    Replies:
    5
    Views:
    2,369
    James Kanze
    Nov 25, 2009
  3. Zoran Lazarevic
    Replies:
    5
    Views:
    183
    Ara.T.Howard
    Oct 8, 2003
  4. Kenneth McDonald
    Replies:
    5
    Views:
    315
    Kenneth McDonald
    Sep 26, 2008
  5. Replies:
    2
    Views:
    104
Loading...

Share This Page