sylvank@syma.sussex.ac.uk (Sylvan Katz) (05/14/91)
I have an application which requires that I initialize an associative array for counting purposes: EG: %matrix = ('A',0,'AA',0,'B',0,'BB',0); However, when I examine the order of the array elements with foreach $key (keys %matrix) { print "$key ";} I find order is BB A B AA Any suggestions on how I can PRESERVE the initial order (it is imperative for my applications) ? Sylvan sylvank@syma.sussex.ac.uk
tchrist@convex.COM (Tom Christiansen) (05/18/91)
From the keyboard of sylvank@syma.sussex.ac.uk (Sylvan Katz): :I have an application which requires that I initialize an associative :array for counting purposes: : :EG: : : %matrix = ('A',0,'AA',0,'B',0,'BB',0); : :However, when I examine the order of the array elements with : : foreach $key (keys %matrix) { print "$key ";} : :I find order is : : BB A B AA : :Any suggestions on how I can PRESERVE the initial order (it is :imperative for my applications) ? If you're not adding any elements to the array, you could do this: @keys = ('A','AA','B','BB'); @matrix{@keys} = (); or, if having the values initialized to undef bothers you: @matrix{@keys} = (0) x @keys; Then process them with: for $key (@keys) { print "key ", $key, " is ", $matrix{$key}, "\n"; } Other more baroque ideas come to mind, like this one, which might perhaps be of use to you if you have some other criteria I'm not aware of: %order = (); $order = 0; for (@keys) { $order{$_} = $order++; } # later on... sub by_order { $order{$a} <=> $order{$b}; } for (sort by_order keys %matrix) { print "key ", $key, " is ", $matrix{$key}, "\n"; } In short, it all else fails, call an auxiliary function to help you get the ordering down. --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "So much mail, so little time."
roger@mav.com (Roger Droz) (05/25/91)
In article <1991May18.160757.15011@convex.com> tchrist@convex.COM (Tom Christiansen) writes: >From the keyboard of sylvank@syma.sussex.ac.uk (Sylvan Katz): >:I have an application which requires that I initialize an associative >:array for counting purposes: >: >:EG: >: >: %matrix = ('A',0,'AA',0,'B',0,'BB',0); >: >:However, when I examine the order of the array elements with >: >: foreach $key (keys %matrix) { print "$key ";} >: >:I find order is >: >: BB A B AA >: >:Any suggestions on how I can PRESERVE the initial order (it is >:imperative for my applications) ? > >If you're not adding any elements to the array, you could do this: > > @keys = ('A','AA','B','BB'); Tom is right about using a second array to preserve order. Perl doesn't preserve order in associative arrays by itself. Unless you explicitly want to keep track of things that occur zero times, there is no reason to initialize the associative array. $matrix{$thing}++ is a fine way to count aribrary things. If you want to count a specific list of things that may occur zero or more times, I agree with Tom: > @matrix{@keys} = (0) x @keys; > >Then process them with: > > for $key (@keys) { > print "key ", $key, " is ", $matrix{$key}, "\n"; > } > Perl will happily count things outside your list of keys without complaint, so you may want to add a sanity check as you count your input data: unless (defined $matrix{$thing}++) { $none_of_above++; } ____________ Roger Droz Domain: roger@mav.COM () () Maverick International UUCP: uw-beaver!gtisqr!roger (_______) Mukilteo, WA ( ) | | Disclaimer: "We're all mavericks here: | | Each of us has our own opinions, (___) and the company has yet different ones!"