Key Associated w/ Maximum Value in Hash

Discussion in 'Ruby' started by Timothy Baron, Sep 9, 2010.

  1. Simple question: what's the cleanest way to retrieve a key associated
    with the maximum value of a hash. For instance, how do I retrieve 'b'
    from the following example:

    hash = Hash.new
    hash['a']=4
    hash['b']=10
    hash['c']=7
    --
    Posted via http://www.ruby-forum.com/.
    Timothy Baron, Sep 9, 2010
    #1
    1. Advertising

  2. Timothy Baron

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Wed, Sep 8, 2010 at 9:57 PM, Timothy Baron <>wrote:

    > Simple question: what's the cleanest way to retrieve a key associated
    > with the maximum value of a hash. For instance, how do I retrieve 'b'
    > from the following example:
    >
    > hash = Hash.new
    > hash['a']=4
    > hash['b']=10
    > hash['c']=7
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >

    How about Enumerable#max

    hash = {'a'=>4,'b'=>10,'c'=>7}
    max_record = hash.max { |a,b| a.last <=> b.last } # => ["b", 10]
    max_index = max_record && max_record.first # => "b"
    Josh Cheek, Sep 9, 2010
    #2
    1. Advertising

  3. On 09.09.2010 05:23, Josh Cheek wrote:

    > On Wed, Sep 8, 2010 at 9:57 PM, Timothy Baron<>wrote:
    >
    >> Simple question: what's the cleanest way to retrieve a key associated
    >> with the maximum value of a hash. For instance, how do I retrieve 'b'
    >> from the following example:
    >>
    >> hash = Hash.new
    >> hash['a']=4
    >> hash['b']=10
    >> hash['c']=7
    >> --
    >> Posted via http://www.ruby-forum.com/.
    >>
    >>

    > How about Enumerable#max
    >
    > hash = {'a'=>4,'b'=>10,'c'=>7}
    > max_record = hash.max { |a,b| a.last<=> b.last } # => ["b", 10]
    > max_index = max_record&& max_record.first # => "b"


    In 1.9.x you can even spare the #last:

    irb(main):001:0> hash = {'a'=>4,'b'=>10,'c'=>7}
    => {"a"=>4, "b"=>10, "c"=>7}
    irb(main):002:0> hash.max {|(k1,v1),(k2,v2)| v1 <=> v2}
    => ["b", 10]

    Here's a version with #inject

    irb(main):004:0> hash.inject([nil,0]) {|(maxk,maxv),(k,v)| v > maxv ?
    [k,v] : [maxk,maxv]}.last
    => 10

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Sep 9, 2010
    #3
  4. On Thu, Sep 9, 2010 at 11:57 AM, Timothy Baron <> wr=
    ote:
    > Simple question: =A0what's the cleanest way to retrieve a key associated
    > with the maximum value of a hash. =A0For instance, how do I retrieve 'b'
    > from the following example:
    >
    > hash =3D Hash.new
    > hash['a']=3D4
    > hash['b']=3D10
    > hash['c']=3D7
    > --


    What if you have more than one max?

    h =3D {'a'=3D>4,'b'=3D>10,'c'=3D>7,'d' =3D> 10}

    p h.select{|x,i| i=3D=3Dh.values.max}.keys #> ["b", "d"]


    Harry
    Harry Kakueki, Sep 9, 2010
    #4
  5. On Thu, Sep 9, 2010 at 2:25 AM, Robert Klemme
    <> wrote:
    > Here's a version with #inject
    >
    > irb(main):004:0> hash.inject([nil,0]) {|(maxk,maxv),(k,v)| v > maxv ? [k,v]
    > : [maxk,maxv]}.last
    > => 10


    But that fails if there are only negative values in the hash.

    hash = {:a => -2, :b => -4}
    hash.inject([nil,0]) {|(maxk,maxv),(k,v)| v > maxv ? [k,v] :
    [maxk,maxv]}.last # => 0

    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Github: http://github.com/rubyredrick
    Twitter: @RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
    Rick DeNatale, Sep 9, 2010
    #5
  6. Brian Candler, Sep 9, 2010
    #6
  7. This won't capture multiple maximum values, but:

    hash.invert[hash.values.max]

    I'd be interested to see a benchmark profile of the suggestions.

    On Thu, Sep 9, 2010 at 4:37 PM, Brian Candler <> wrote:
    > hash.sort_by { |k,v| v }[-1][0]
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
    Adam Prescott, Sep 9, 2010
    #7
  8. I've tried several of these approaches, and they all work well. I'm
    curious, too, about which is the fastest, but for my small hashs,
    there's no noticable difference.

    Adam Prescott wrote:
    > This won't capture multiple maximum values, but:
    >
    > hash.invert[hash.values.max]
    >
    > I'd be interested to see a benchmark profile of the suggestions.


    --
    Posted via http://www.ruby-forum.com/.
    Timothy Baron, Sep 10, 2010
    #8
  9. Timothy Baron

    Ben Giddings Guest

    On Sep 9, 2010, at 23:00, Timothy Baron wrote:
    > I've tried several of these approaches, and they all work well. I'm
    > curious, too, about which is the fastest, but for my small hashs,
    > there's no noticable difference.


    Don't bother optimizing it for speed unless you are sure it's a
    bottleneck. Choose whichever option is the most readable and
    maintainable.

    Ben
    Ben Giddings, Sep 10, 2010
    #9
  10. [Note: parts of this message were removed to make it a legal post.]

    For fun:

    http://www.pastie.org/1153968

    $ ruby -v
    ruby 1.9.1p378 (2010-01-10 revision 26273) [x86_64-linux]
    $ ruby max_hash_value.rb
    {0=>-18, 1=>-5, 2=>-31, 3=>44, 4=>-13, 5=>-1, 6=>23, 7=>5, 8=>22, 9=>37}
    user system total real
    max 0.110000 0.000000 0.110000 ( 0.270811)
    max 1.9.X 0.090000 0.000000 0.090000 ( 0.242181)
    select 0.430000 0.000000 0.430000 ( 1.270329)
    select (cache max) 0.080000 0.000000 0.080000 ( 0.147179)
    sort_by 0.160000 0.000000 0.160000 ( 0.438671)
    invert 0.080000 0.000000 0.080000 ( 0.279259)
    invert (cache max) 0.060000 0.000000 0.060000 ( 0.155440)


    On Fri, Sep 10, 2010 at 5:20 AM, Ben Giddings <>wrote:

    > On Sep 9, 2010, at 23:00, Timothy Baron wrote:
    >
    >> I've tried several of these approaches, and they all work well. I'm
    >> curious, too, about which is the fastest, but for my small hashs,
    >> there's no noticable difference.
    >>

    >
    > Don't bother optimizing it for speed unless you are sure it's a bottleneck.
    > Choose whichever option is the most readable and maintainable.
    >
    > Ben
    >
    >
    >
    >
    Douglas Seifert, Sep 12, 2010
    #10
  11. On 12 September 2010 18:29, Douglas Seifert <> wrote:
    > For fun:
    > http://www.pastie.org/1153968
    >

    To keep the fun going :)
    http://gist.github.com/576279

    I wonder why nobody used Enumerable#max_by or Hash#key (#index in 1.8):
    HASH.max_by(&:last).first
    HASH.key HASH.values.max
    And it reveals there are both relatively efficient.

    I could not help to DRY a bit the tests ;)

    Regards,
    B.D.
    Benoit Daloze, Sep 12, 2010
    #11
    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. rp
    Replies:
    1
    Views:
    516
    red floyd
    Nov 10, 2011
  2. Une bévue
    Replies:
    5
    Views:
    148
    Une bévue
    Aug 10, 2006
  3. Antonio Quinonez
    Replies:
    2
    Views:
    167
    Antonio Quinonez
    Aug 14, 2003
  4. Ralf Baerwaldt
    Replies:
    1
    Views:
    131
    Paul Lalli
    Jul 20, 2004
  5. Robert Manea

    Maximum length of hash key

    Robert Manea, Dec 8, 2004, in forum: Perl Misc
    Replies:
    14
    Views:
    918
    Tad McClellan
    Dec 9, 2004
Loading...

Share This Page