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

Re: [PBML] Re: sorting a hash using its value

Expand Messages
  • richardb@stats.st.com.sg
    Hi Damien, Thanks, it worked, but I need also to know the corresponding key of that first 3 values? BRgds, Richard Damien Carbery
    Message 1 of 5 , Jul 2, 2003
    • 0 Attachment
      Hi Damien,
      Thanks, it worked, but I need also to know the corresponding key of that
      first 3 values?

      BRgds,
      Richard



      "Damien Carbery" <daymobrew@...> 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 );




      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]
    • 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 2 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 3 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 4 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 5 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.