Sorting a multi-dimensional hash

Discussion in 'Perl Misc' started by ifiaz, Nov 11, 2003.

  1. ifiaz

    ifiaz Guest

    Problem:

    I populate a hash %Fnd with the following data
    it loops through the file with 300000 lines of data.

    ###CODE

    while (<>) {

    if ( something == somethingelse) {

    $Fnd{$Lic}{Count}++;

    $cF = $Fnd{$Lic}{Count};

    $Fnd{$Lic}{$cF}{ScanTimeDt} = substr($mScanTimeDt, 6, 2);
    $Fnd{$Lic}{$cF}{ScanTime} = $ScanTime; #090000 (Sample Data)
    $Fnd{$Lic}{$cF}{mFullScanTime} = $mFullScanTime; #20030317090000 (Sample data)
    $Fnd{$Lic}{$cF}{IUMethod} = $IUMethod;
    $Fnd{$Lic}{$cF}{IU} = $IU;
    $Fnd{$Lic}{$cF}{Carrier} = $Carrier;
    $Fnd{$Lic}{$cF}{CarCode} = $CarCode;
    $Fnd{$Lic}{$cF}{FlightNo} = $FlightNo;
    $Fnd{$Lic}{$cF}{Chute} = $Chute;
    $Fnd{$Lic}{$cF}{TiltTimeDt} = substr($mTiltTimeDt, 6, 2);
    $Fnd{$Lic}{$cF}{mTiltTimeDy} = $mTiltTimeDy;
    $Fnd{$Lic}{$cF}{mTiltTime} = $mTiltTime;
    $Fnd{$Lic}{$cF}{TStamp} = $TStamp;

    }

    }

    ###Looping through files end here.

    ## After the %Fnd is populated, I do a display of
    ## it in the appropriate format.

    foreach $tmpLic (sort keys %Fnd) {

    # do a display of the %Fnd hash one by one

    }

    __END__

    Initially above loop was used to display, but later I
    realize that I need to sort the hash not by the $Lic
    in $Fnd{$Lic} but by the $Fnd{$Lic}{$Cf}{mFullScanTime}.

    How can I have the hash sorted by my requirement?

    I have tried various ways from newsgroups examples, etc.
    but eventually fail. Could someone please help with
    layman terms?

    I am able to sort the hash when it is just one or two
    dimensions but not more. I get utterly confused when
    the gets more than two dimension.

    I am newbie to perl actually to programming itself.


    Thanks.
     
    ifiaz, Nov 11, 2003
    #1
    1. Advertising

  2. ifiaz

    Anno Siegel Guest

    ifiaz <> wrote in comp.lang.perl.misc:
    > Problem:
    >
    > I populate a hash %Fnd with the following data
    > it loops through the file with 300000 lines of data.
    >
    > ###CODE


    No. What follows is pseudo-code. You improve your chances of getting
    useful replies when you post runnable code.

    > while (<>) {
    >
    > if ( something == somethingelse) {
    >
    > $Fnd{$Lic}{Count}++;
    >
    > $cF = $Fnd{$Lic}{Count};
    >
    > $Fnd{$Lic}{$cF}{ScanTimeDt} = substr($mScanTimeDt, 6, 2);
    > $Fnd{$Lic}{$cF}{ScanTime} = $ScanTime; #090000 (Sample Data)
    > $Fnd{$Lic}{$cF}{mFullScanTime} = $mFullScanTime; #20030317090000 (Sample data)

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > $Fnd{$Lic}{$cF}{IUMethod} = $IUMethod;
    > $Fnd{$Lic}{$cF}{IU} = $IU;
    > $Fnd{$Lic}{$cF}{Carrier} = $Carrier;
    > $Fnd{$Lic}{$cF}{CarCode} = $CarCode;
    > $Fnd{$Lic}{$cF}{FlightNo} = $FlightNo;
    > $Fnd{$Lic}{$cF}{Chute} = $Chute;
    > $Fnd{$Lic}{$cF}{TiltTimeDt} = substr($mTiltTimeDt, 6, 2);
    > $Fnd{$Lic}{$cF}{mTiltTimeDy} = $mTiltTimeDy;
    > $Fnd{$Lic}{$cF}{mTiltTime} = $mTiltTime;
    > $Fnd{$Lic}{$cF}{TStamp} = $TStamp;


    Why let everyone wade through all these lines? The only one relevant
    to the problem is the one I highlighted.

    > }
    >
    > }


    Please learn how to indent properly. Again, the more readable your code
    is, the better are your chances that someone will actually read it.

    > ###Looping through files end here.
    >
    > ## After the %Fnd is populated, I do a display of
    > ## it in the appropriate format.
    >
    > foreach $tmpLic (sort keys %Fnd) {
    >
    > # do a display of the %Fnd hash one by one
    >
    > }
    >
    > __END__
    >
    > Initially above loop was used to display, but later I
    > realize that I need to sort the hash not by the $Lic
    > in $Fnd{$Lic} but by the $Fnd{$Lic}{$Cf}{mFullScanTime}.


    You mean, sorting the hash *keys*.

    > How can I have the hash sorted by my requirement?


    By supplying the corresponding comparison routinei (untested):

    sort { $Fnd{$a}{$Cf}{mFullScanTime} <=> $Fnd{$b}{$Cf}{mFullScanTime} }
    keys %Fnd;

    Anno
     
    Anno Siegel, Nov 11, 2003
    #2
    1. Advertising

  3. ifiaz

    ifiaz Guest

    > No. What follows is pseudo-code. You improve your chances of getting
    > useful replies when you post runnable code.
    >
    > > $Fnd{$Lic}{$cF}{mFullScanTime} = $mFullScanTime; #20030317090000 (Sample data)

    > Why let everyone wade through all these lines? The only one relevant
    > to the problem is the one I highlighted.
    > Please learn how to indent properly. Again, the more readable your code
    > is, the better are your chances that someone will actually read it.


    Thanks for pointing out. I will follow accordingly.

    > You mean, sorting the hash *keys*.


    I think by value. i.e. $Fnd{$Lic}{$cF}{mFullScanTime} = "20030317090000"
    so I need to sort by the scan times on the right hand side of equal sign.

    > > How can I have the hash sorted by my requirement?

    >
    > By supplying the corresponding comparison routinei (untested):
    >
    > sort { $Fnd{$a}{$Cf}{mFullScanTime} <=> $Fnd{$b}{$Cf}{mFullScanTime} }
    > keys %Fnd;
    >


    One typical example is

    $Fnd{"00123"}{"1"}{mFullScanTime} = ...
    $Fnd{"00123"}{"2"}{mFullScanTime} = ...
    $Fnd{"00123"}{"3"}{mFullScanTime} = ...
    $Fnd{"00123"}{"4"}{mFullScanTime} = ...
    $Fnd{"12345"}{"1"}{mFullScanTime} = ...
    $Fnd{"12346"}{"1"}{mFullScanTime} = ...

    Since, $cF is a variable that changes everytime, I don't know how
    to pass the $cF inside the sort routine. So, I need to know how
    I can pass the $cF inside the sort routine, so that the sort routine
    can refer to each and every mFullScanTime of $Lic and $cF put
    together and return the sorted result.

    I am completely new to this. If my question is not phrased correctly
    above, I apologise.
     
    ifiaz, Nov 12, 2003
    #3
  4. ifiaz

    Anno Siegel Guest

    ifiaz <> wrote in comp.lang.perl.misc:
    > > No. What follows is pseudo-code. You improve your chances of getting
    > > useful replies when you post runnable code.
    > >
    > > > $Fnd{$Lic}{$cF}{mFullScanTime} = $mFullScanTime; #20030317090000

    > (Sample data)
    > > Why let everyone wade through all these lines? The only one relevant
    > > to the problem is the one I highlighted.
    > > Please learn how to indent properly. Again, the more readable your code
    > > is, the better are your chances that someone will actually read it.

    >
    > Thanks for pointing out. I will follow accordingly.
    >
    > > You mean, sorting the hash *keys*.

    >
    > I think by value. i.e. $Fnd{$Lic}{$cF}{mFullScanTime} = "20030317090000"
    > so I need to sort by the scan times on the right hand side of equal sign.
    >
    > > > How can I have the hash sorted by my requirement?

    > >
    > > By supplying the corresponding comparison routinei (untested):
    > >
    > > sort { $Fnd{$a}{$Cf}{mFullScanTime} <=> $Fnd{$b}{$Cf}{mFullScanTime} }
    > > keys %Fnd;
    > >

    >
    > One typical example is
    >
    > $Fnd{"00123"}{"1"}{mFullScanTime} = ...
    > $Fnd{"00123"}{"2"}{mFullScanTime} = ...
    > $Fnd{"00123"}{"3"}{mFullScanTime} = ...
    > $Fnd{"00123"}{"4"}{mFullScanTime} = ...
    > $Fnd{"12345"}{"1"}{mFullScanTime} = ...
    > $Fnd{"12346"}{"1"}{mFullScanTime} = ...
    >
    > Since, $cF is a variable that changes everytime, I don't know how
    > to pass the $cF inside the sort routine. So, I need to know how
    > I can pass the $cF inside the sort routine, so that the sort routine
    > can refer to each and every mFullScanTime of $Lic and $cF put
    > together and return the sorted result.


    The operative term here is "put together". Apparently, every hash
    entry can have multiple mFullScanTime's. The question is, how are
    you going to use these for sorting? Pick one? If so, which one?
    Use the average? Something else?

    Without an answer to this there isn't much I can suggest.

    Anno
     
    Anno Siegel, Nov 12, 2003
    #4
  5. ifiaz

    ifiaz Guest

    > > > sort { $Fnd{$a}{$Cf}{mFullScanTime} <=> $Fnd{$b}{$Cf}{mFullScanTime} }
    > > > keys %Fnd;
    > > >

    > >

    >
    > The operative term here is "put together". Apparently, every hash
    > entry can have multiple mFullScanTime's. The question is, how are
    > you going to use these for sorting? Pick one? If so, which one?
    > Use the average? Something else?
    >
    > Without an answer to this there isn't much I can suggest.
    >


    With help from your previous posting and a bit of trial and error
    (actually several trials and errors), I managed to do the sorting.

    Here it goes:

    foreach $tmpLic (sort keys %Fnd) {
    ...
    foreach $tmpCount (sort byScanTime keys %{$Fnd{$tmpLic}}) {
    ...
    ...
    write;
    }
    }

    ##sort routine
    sub byScanTime() {
    $Fnd{$tmpLic}{$a}{mFullScanTime} <=>
    $Fnd{$tmpLic}{$b}{mFullScanTime}
    }

    __END__

    Although, I don't understand completely how it works, but I guess
    I will manage to do the same with trial and error, next time I face it in a
    different scenario.

    Thank you.
     
    ifiaz, Nov 13, 2003
    #5
  6. ifiaz <> wrote:

    > ##sort routine
    > sub byScanTime() {



    > Although, I don't understand completely how it works,



    You can put some print() statements in the body of byScanTime()
    and see what goes by...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Nov 13, 2003
    #6
    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. Simon Brunning
    Replies:
    5
    Views:
    518
    Peter Otten
    Jun 9, 2007
  2. Replies:
    2
    Views:
    1,400
    Marcel Müller
    Jan 4, 2009
  3. rp
    Replies:
    1
    Views:
    594
    red floyd
    Nov 10, 2011
  4. Wirianto Djunaidi
    Replies:
    2
    Views:
    229
    Wirianto Djunaidi
    Apr 29, 2008
  5. David Sainte-claire

    Dynamically creating a multi dimensional hash

    David Sainte-claire, Aug 11, 2009, in forum: Ruby
    Replies:
    2
    Views:
    435
    Joel VanderWerf
    Aug 11, 2009
Loading...

Share This Page