Loading ...
Sorry, an error occurred while loading the content.

[PBML] Re: sorting a hash using its value

Expand Messages
  • Damien Carbery
    ... test ... that ... # Exchange the keys and values. my %newhash = map { $hash{ $_ } = $_ } keys %hash; # %newhash = ( 2= 1, 10= 2, 4= 3, 3= 4, 12= 5 ); You
    Message 1 of 5 , Jul 2, 2003
    • 0 Attachment
      --- In perl-beginner@yahoogroups.com, richardb@s... wrote:
      >
      > "Damien Carbery" <daymobrew@y...> 02/07/2003 04:48 PM
      > Please respond to perl-beginner
      >
      > To: perl-beginner@yahoogroups.com
      > cc: (bcc: BORNAY Richard/Engr/STATS/ST Group)
      > Subject: [PBML] Re: sorting a hash using its value
      >
      >
      >
      >
      >
      >
      >
      >
      > --- In perl-beginner@yahoogroups.com, richardb@s... wrote:
      > > I'm having difficulty in getting the first 3 highest values in a
      > hash, can
      > > somebody help me (spending many hours, figuring this out)
      > > e.g
      > > %hash=(
      > > 1=>2,
      > > 2=>10,
      > > 3=>4,
      > > 4=>3,
      > > 5=>12
      > > );
      > >
      > > I want to get only the values 12, 10 & 4. This actually came from
      test
      > > data, one column is the bin number(which is unique) and
      > > another column(which is the count), then from this two parameters, I
      > > created a hash (like the example above), the bin number
      > > is the key and count is the value..
      > >
      > > Appreciate your help..
      > >
      > > Thanks..
      > >
      > >
      > >
      > > BRgds,
      > > --
      > > Richard Bornay
      > > Test Product Engineering
      > > Test Data Management Group
      > > ST Assembly Test Services
      > > 6824-1367
      > >
      > > [Non-text portions of this message have been removed]
      >
      > Use 'values( %hash )'
      > It returns a list of the values from the hash.
      >
      > So, this untested code might work:
      > # The '$a <=> $b' does a numeric sort of the values.
      > my @SortedList = sort { $a <=> $b } values %hash;
      > # Drop elements 3+ i.e. keep top 3 values.
      > splice( @SortedList, 2 );
      >
      >
      > Hi Damien,
      > Thanks, it worked, but I need also to know the corresponding key of
      that
      > first 3 values?
      >
      > BRgds,
      > Richard
      >

      # Exchange the keys and values.
      my %newhash = map { $hash{ $_ } => $_ } keys %hash;
      # %newhash = ( 2=>1, 10=>2, 4=>3, 3=>4, 12=>5 );

      You can now sort the on the keys
      my @SortedList = reverse sort { $a <=> $b } values %hash;
      and use the value to find out what the original key was.

      I'm sure Jeff, Charles and Jenda will have nicer, less confusing,
      solutions.
      It would be good to know what you want to do with the results and why
      you need the keys.
    • richardb@stats.st.com.sg
      Hi Damien, I m actually extracting these data(bin num and corresponding value) from a testing summary files, these parameters are being used for test analysis.
      Message 2 of 5 , Jul 2, 2003
      • 0 Attachment
        Hi Damien,
        I'm actually extracting these data(bin num and corresponding value) from a
        testing summary files, these parameters
        are being used for test analysis. The 3 most highest values need to be
        reported, the actual format of the report
        will look like this,


        #### sample report format #####
        1st_bin_num | 1st_highest_bin_num_qty | 2nd_bin_num | 2nd_highest_bin_num
        | 3rd_bin_num | 3rd_highest_bin_num

        note: | - delimiter

        So once I know the first three highest values, I need also the
        corresponding bin number (w/c is the key) and will
        be printed in a report file with the above format..

        I usually do this kind of scripting but there's a lot of summary file
        format which for this one I'm having
        difficulty..

        Thank you very much for your time...

        Hi Jeff, Charles and Jenda,
        Hope you can help me with this, will appreciate it very much....thanks in
        advance..

        BRgds,
        --
        Richard Bornay
        Test Product Engineering
        Test Data Management Group
        ST Assembly Test Services
        6824-1367


        "Damien Carbery" <daymobrew@...> 02/07/2003 05:58 PM
        Please respond to perl-beginner

        To: perl-beginner@yahoogroups.com
        cc: (bcc: BORNAY Richard/Engr/STATS/ST Group)
        Subject: [PBML] Re: sorting a hash using its value








        --- In perl-beginner@yahoogroups.com, richardb@s... wrote:
        >
        > "Damien Carbery" <daymobrew@y...> 02/07/2003 04:48 PM
        > Please respond to perl-beginner
        >
        > To: perl-beginner@yahoogroups.com
        > cc: (bcc: BORNAY Richard/Engr/STATS/ST Group)
        > Subject: [PBML] Re: sorting a hash using its value
        >
        >
        >
        >
        >
        >
        >
        >
        > --- In perl-beginner@yahoogroups.com, richardb@s... wrote:
        > > I'm having difficulty in getting the first 3 highest values in a
        > hash, can
        > > somebody help me (spending many hours, figuring this out)
        > > e.g
        > > %hash=(
        > > 1=>2,
        > > 2=>10,
        > > 3=>4,
        > > 4=>3,
        > > 5=>12
        > > );
        > >
        > > I want to get only the values 12, 10 & 4. This actually came from
        test
        > > data, one column is the bin number(which is unique) and
        > > another column(which is the count), then from this two parameters, I
        > > created a hash (like the example above), the bin number
        > > is the key and count is the value..
        > >
        > > Appreciate your help..
        > >
        > > Thanks..
        > >
        > >
        > >
        > > BRgds,
        > > --
        > > Richard Bornay
        > > Test Product Engineering
        > > Test Data Management Group
        > > ST Assembly Test Services
        > > 6824-1367
        > >
        > > [Non-text portions of this message have been removed]
        >
        > Use 'values( %hash )'
        > It returns a list of the values from the hash.
        >
        > So, this untested code might work:
        > # The '$a <=> $b' does a numeric sort of the values.
        > my @SortedList = sort { $a <=> $b } values %hash;
        > # Drop elements 3+ i.e. keep top 3 values.
        > splice( @SortedList, 2 );
        >
        >
        > Hi Damien,
        > Thanks, it worked, but I need also to know the corresponding key of
        that
        > first 3 values?
        >
        > BRgds,
        > Richard
        >

        # Exchange the keys and values.
        my %newhash = map { $hash{ $_ } => $_ } keys %hash;
        # %newhash = ( 2=>1, 10=>2, 4=>3, 3=>4, 12=>5 );

        You can now sort the on the keys
        my @SortedList = reverse sort { $a <=> $b } values %hash;
        and use the value to find out what the original key was.

        I'm sure Jeff, Charles and Jenda will have nicer, less confusing,
        solutions.
        It would be good to know what you want to do with the results and why
        you need the keys.




        Unsubscribing info is here: http://help.yahoo.com/help/us/groups/groups-32.html

        Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/






        [Non-text portions of this message have been removed]
      • Charles K. Clarkson
        ... Do you need the hash for something else or are you using it just for this operation? If the answer is no, place your data into an array of arrays. If yes,
        Message 3 of 5 , Jul 2, 2003
        • 0 Attachment
          richardb@... <richardb@...> wrote:
          :
          : I'm actually extracting these data(bin num and
          : corresponding value) from a testing summary files,
          : these parameters are being used for test analysis.
          : The 3 most highest values need to be reported, the
          : actual format of the report will look like this,
          :
          :
          : #### sample report format #####
          : 1st_bin_num | 1st_highest_bin_num_qty | 2nd_bin_num |
          : 2nd_highest_bin_num
          : | 3rd_bin_num | 3rd_highest_bin_num
          :
          : note: | - delimiter
          :
          : So once I know the first three highest values, I need
          : also the corresponding bin number (w/c is the key)
          : and will be printed in a report file with the above
          : format..

          Do you need the hash for something else
          or are you using it just for this operation?
          If the answer is no, place your data into
          an array of arrays. If yes, treat the hash
          as two arrays.

          The NO solution:

          my @bins = (
          [ 1, 2 ],
          [ 2, 10 ],
          [ 3, 4 ],
          [ 4, 3 ],
          [ 5, 12 ],
          );

          # reverse sort indexes by second column
          my @indexes = sort { $bins[ $b ][ 1 ] <=> $bins[ $a ][ 1 ] } 0 ..
          $#bins;

          my @result;
          foreach ( @bins[ @indexes[ 0 .. 2] ] ) {
          push @result, @{ $_ }[ 0, 1 ];
          }

          print join ' | ', @result;

          __END__

          Or:

          my @bins = (
          [ 1, 2 ],
          [ 2, 10 ],
          [ 3, 4 ],
          [ 4, 3 ],
          [ 5, 12 ],
          );

          my @result;
          push @result, @{ $_ }[ 0, 1 ] foreach
          @bins[ ( sort { $bins[ $b ][ 1 ] <=> $bins[ $a ][ 1 ] } 0 .. $#bins
          )[ 0 .. 2] ];

          print join ' | ', @result;

          __END__





          ========================================================
          The YES solution:

          my %bins = (
          1 => 2,
          2 => 10,
          3 => 4,
          4 => 3,
          5 => 12,
          );

          # grab the values
          my @counts = values %bins;

          # sort the indexes of @counts in descending order
          my @indexes = sort { $counts[ $b ] <=> $counts[ $a ] } 0 .. $#counts;

          # grab the keys - this will be
          # in the same order as values
          my @bins = keys %bins;

          my @keys_to_three_highest_values = @bins[ @indexes[ 0 .. 2 ] ];

          my @result;
          foreach ( @keys_to_three_highest_values ) {
          push @result, $_, $bins{ $_ };
          }

          print join ' | ', @result;

          __END__

          Or:

          my %bins = (
          1 => 2,
          2 => 10,
          3 => 4,
          4 => 3,
          5 => 12,
          );

          # grab the values
          my @counts = values %bins;

          my @result;
          foreach ( ( keys %bins )[ ( sort { $counts[ $b ] <=> $counts[ $a ] } 0
          .. $#counts )[ 0 .. 2 ] ] ) {
          push @result, $_, $bins{ $_ };
          }

          print join ' | ', @result;

          __END__

          One problem I see is what happens if 4 or
          more counts are equal and in the first place.
          The routines above arbitrarily picks three
          of the ties.


          HTH,

          Charles K. Clarkson
          --
          Head Bottle Washer,
          Clarkson Energy Homes, Inc.
          Mobile Home Specialists
          254 968-8328
        • richardb@stats.st.com.sg
          Hi Charles, Thank you very much for your given solutions to my query, I find your programming logic truly amazing... I used option 2 ( and it already worked )
          Message 4 of 5 , Jul 2, 2003
          • 0 Attachment
            Hi Charles,
            Thank you very much for your given solutions to my query,
            I find your programming logic truly amazing...

            I used option 2 ( and it already worked ) since I only need it that
            operation but I will
            keep option 1 in case I will encounter it in the future...

            Thanks also, Damien...


            BRgds,
            --
            Richard Bornay
            Test Product Engineering
            Test Data Management Group
            ST Assembly Test Services
            6824-1367


            "Charles K. Clarkson" <cclarkson@...> 03/07/2003 02:40 AM
            Please respond to perl-beginner

            To: <perl-beginner@yahoogroups.com>
            cc: (bcc: BORNAY Richard/Engr/STATS/ST Group)
            Subject: RE: [PBML] Re: sorting a hash using its value








            richardb@... <richardb@...> wrote:
            :
            : I'm actually extracting these data(bin num and
            : corresponding value) from a testing summary files,
            : these parameters are being used for test analysis.
            : The 3 most highest values need to be reported, the
            : actual format of the report will look like this,
            :
            :
            : #### sample report format #####
            : 1st_bin_num | 1st_highest_bin_num_qty | 2nd_bin_num |
            : 2nd_highest_bin_num
            : | 3rd_bin_num | 3rd_highest_bin_num
            :
            : note: | - delimiter
            :
            : So once I know the first three highest values, I need
            : also the corresponding bin number (w/c is the key)
            : and will be printed in a report file with the above
            : format..

            Do you need the hash for something else
            or are you using it just for this operation?
            If the answer is no, place your data into
            an array of arrays. If yes, treat the hash
            as two arrays.

            The NO solution:

            my @bins = (
            [ 1, 2 ],
            [ 2, 10 ],
            [ 3, 4 ],
            [ 4, 3 ],
            [ 5, 12 ],
            );

            # reverse sort indexes by second column
            my @indexes = sort { $bins[ $b ][ 1 ] <=> $bins[ $a ][ 1 ] } 0 ..
            $#bins;

            my @result;
            foreach ( @bins[ @indexes[ 0 .. 2] ] ) {
            push @result, @{ $_ }[ 0, 1 ];
            }

            print join ' | ', @result;

            __END__

            Or:

            my @bins = (
            [ 1, 2 ],
            [ 2, 10 ],
            [ 3, 4 ],
            [ 4, 3 ],
            [ 5, 12 ],
            );

            my @result;
            push @result, @{ $_ }[ 0, 1 ] foreach
            @bins[ ( sort { $bins[ $b ][ 1 ] <=> $bins[ $a ][ 1 ] } 0 .. $#bins
            )[ 0 .. 2] ];

            print join ' | ', @result;

            __END__





            ========================================================
            The YES solution:

            my %bins = (
            1 => 2,
            2 => 10,
            3 => 4,
            4 => 3,
            5 => 12,
            );

            # grab the values
            my @counts = values %bins;

            # sort the indexes of @counts in descending order
            my @indexes = sort { $counts[ $b ] <=> $counts[ $a ] } 0 .. $#counts;

            # grab the keys - this will be
            # in the same order as values
            my @bins = keys %bins;

            my @keys_to_three_highest_values = @bins[ @indexes[ 0 .. 2 ] ];

            my @result;
            foreach ( @keys_to_three_highest_values ) {
            push @result, $_, $bins{ $_ };
            }

            print join ' | ', @result;

            __END__

            Or:

            my %bins = (
            1 => 2,
            2 => 10,
            3 => 4,
            4 => 3,
            5 => 12,
            );

            # grab the values
            my @counts = values %bins;

            my @result;
            foreach ( ( keys %bins )[ ( sort { $counts[ $b ] <=> $counts[ $a ] } 0
            .. $#counts )[ 0 .. 2 ] ] ) {
            push @result, $_, $bins{ $_ };
            }

            print join ' | ', @result;

            __END__

            One problem I see is what happens if 4 or
            more counts are equal and in the first place.
            The routines above arbitrarily picks three
            of the ties.


            HTH,

            Charles K. Clarkson
            --
            Head Bottle Washer,
            Clarkson Energy Homes, Inc.
            Mobile Home Specialists
            254 968-8328
















            Unsubscribing info is here: http://help.yahoo.com/help/us/groups/groups-32.html

            Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/






            [Non-text portions of this message have been removed]
          Your message has been successfully submitted and would be delivered to recipients shortly.