Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: sorting a complex multidimensional hash

by BrowserUk (Pope)
on Jul 22, 2004 at 03:15 UTC ( #376452=note: print w/ replies, xml ) Need Help??


in reply to sorting a complex multidimensional hash

Also an ST, but it sorts both levels

#! perl -slw use strict; use Data::Dumper; my $value = 1; ## Set up some test data my %hash = map{ $_ => { map{ $_ => $value++ } map{ my $digit = $_; map{ "$digit.$_" } 'A' .. 'C' } 1 .. 3 } } map{ my $digit = $_; map{ "$digit.$_" } 'A' .. 'C' } 1 .. 3; # print Dumper \%hash; ## Sort and print print for map{ "{$_->[ 0 ]}{$_->[ 1 ]} => $hash{ $_->[ 0 ] }{ $_->[ 1 ] }" } sort { $a->[ 2 ] <=> $b->[ 2 ] || $a->[ 3 ] cmp $b->[ 3 ] || $a->[ 4 ] <=> $b->[ 4 ] || $a->[ 5 ] cmp $b->[ 5 ] } map{ my $key1 = $_; my( $n1, $l1 ) = $key1 =~ m[(^\d+)\.(.*)]; map{ my( $n2, $l2 ) = $_ =~ m[(^\d+)\.(.*)]; [ $key1, $_, $n1, $l1, $n2, $l2 ] } keys %{ $hash{ $_ } } } keys %hash; __OUTPUT__ P:\test>junk {1.A}{1.A} => 1 {1.A}{1.B} => 2 {1.A}{1.C} => 3 {1.A}{2.A} => 4 {1.A}{2.B} => 5 {1.A}{2.C} => 6 {1.A}{3.A} => 7 {1.A}{3.B} => 8 {1.A}{3.C} => 9 {1.B}{1.A} => 10 {1.B}{1.B} => 11 {1.B}{1.C} => 12 {1.B}{2.A} => 13 {1.B}{2.B} => 14 {1.B}{2.C} => 15 {1.B}{3.A} => 16 {1.B}{3.B} => 17 {1.B}{3.C} => 18 {1.C}{1.A} => 19 {1.C}{1.B} => 20 {1.C}{1.C} => 21 {1.C}{2.A} => 22 {1.C}{2.B} => 23 {1.C}{2.C} => 24 {1.C}{3.A} => 25 {1.C}{3.B} => 26 {1.C}{3.C} => 27 {2.A}{1.A} => 28 {2.A}{1.B} => 29 {2.A}{1.C} => 30 {2.A}{2.A} => 31 {2.A}{2.B} => 32 {2.A}{2.C} => 33 {2.A}{3.A} => 34 {2.A}{3.B} => 35 {2.A}{3.C} => 36 {2.B}{1.A} => 37 {2.B}{1.B} => 38 {2.B}{1.C} => 39 {2.B}{2.A} => 40 {2.B}{2.B} => 41 {2.B}{2.C} => 42 {2.B}{3.A} => 43 {2.B}{3.B} => 44 {2.B}{3.C} => 45 {2.C}{1.A} => 46 {2.C}{1.B} => 47 {2.C}{1.C} => 48 {2.C}{2.A} => 49 {2.C}{2.B} => 50 {2.C}{2.C} => 51 {2.C}{3.A} => 52 {2.C}{3.B} => 53 {2.C}{3.C} => 54 {3.A}{1.A} => 55 {3.A}{1.B} => 56 {3.A}{1.C} => 57 {3.A}{2.A} => 58 {3.A}{2.B} => 59 {3.A}{2.C} => 60 {3.A}{3.A} => 61 {3.A}{3.B} => 62 {3.A}{3.C} => 63 {3.B}{1.A} => 64 {3.B}{1.B} => 65 {3.B}{1.C} => 66 {3.B}{2.A} => 67 {3.B}{2.B} => 68 {3.B}{2.C} => 69 {3.B}{3.A} => 70 {3.B}{3.B} => 71 {3.B}{3.C} => 72 {3.C}{1.A} => 73 {3.C}{1.B} => 74 {3.C}{1.C} => 75 {3.C}{2.A} => 76 {3.C}{2.B} => 77 {3.C}{2.C} => 78 {3.C}{3.A} => 79 {3.C}{3.B} => 80 {3.C}{3.C} => 81

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon


Comment on Re: sorting a complex multidimensional hash
Download Code
Re^2: sorting a complex multidimensional hash
by envirodug (Novice) on Jul 22, 2004 at 03:28 UTC
    good stuff! many thanks!
Re^2: sorting a complex multidimensional hash
by BrowserUk (Pope) on Jul 22, 2004 at 12:38 UTC

    Since there has been all the dicussion regarding ST -v- GRT, here's an multi-level GRT version. Runs about twice as fast.

    print for map{ substr( $_, 1+index( $_, '|' ) ) } sort map { my $key1 = $_; map { pack 'NA* NA* A1 A*', split( '\.', $key1 ), split( '\.', $_ ), '|', $hash{ $key1 }{ $_ } } keys %{ $hash{ $_ } }; } keys %hash;

    Just plug it into the test script above to see it run.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
      You may be giving perl a bad reputation! Terse? No, not at all!
      Seriously, I'm impressed but glad I don't have to maintain it!
      Twice as fast you say. Hmmm. Tempting...

        You should see the recursive version for processing arbitrarially deep nested hashes :)

        On a serious note. I find short to be good for mainatainence. It may require me to look longer before I start making changes, but I consider that a good thing.

        Too many times I've been bitten by zeroing in on what looked to be (or the comments indicated as), a self contained piece of code, only to find out later that there was another piece just off screen that was affected.

        It's a personal thing, but if I don't understand a piece of code froom reading it, then I prefer to experiment (in a test program or with the debugger) until I do, rather than be swayed into believing that I understand it by reading another programmer's, or even my own, comments.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
      i can definately handle faster ...

      question: the output from the first example was formatted as following:  "{$_->[ 0 ]}{$_->[ 1 ]} => $hash{ $_->[ 0 ] }{ $_->[ 1 ] }"

      the output from the new example prints the 'values' of the hash: substr( $_, 1+index( $_, '|' ) ).

      i tried substituting "{$_->[ 0 ]}{$_->[ 1 ]} => $hash{ $_->[ 0 ] }{ $_->[ 1 ] }" from the first example into the second example where substr( $_, 1+index( $_, '|' ) ) was found, but i'm seeing an error: Can't use string ("") as an ARRAY ref while "strict refs" in use at ./test4.pl line 42

      would anyone know how I would need to format this code ({$_->[ 0 ]}{$_->[ 1 ]} => $hash{ $_->[ 0 ] }{ $_->[ 1 ] }) to work in the second example and print information formatted similar to the first example? (i know enough perl to 'get myself in trouble')

      again, many thanks for everyone's help

        That's not too hard to do:

        print for map{ my( $n1, $a1, $n2, $a2, $value ) = unpack 'N A4 N A4 A*', $_; "{$n1.$a1}{$n2.$a2} => $value" } sort map { my $key1 = $_; map { pack 'N A4 N A4 A*', split( '\.', $key1 ), split( '\.', $_ ), $hash{ $key1 }{ $_ } } keys %{ $hash{ $_ } }; } keys %hash;

        but it does introduce a limitation.

        As coded above, the character part of the keys is limited to 4 characters each. They can be shorter but no longer. If this isn't long enough, you must adjust the formats ( 'N A4 N A4 A*' ) to say 'N A10 N A10 A*' for up to 10 chars, in both the pack and the unpack.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://376452]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2014-07-12 16:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (240 votes), past polls