Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!uunet!convex!usenet From: tchrist@convex.COM (Tom Christiansen) Newsgroups: comp.lang.perl Subject: Re: Sortin based on part of an associative array? Message-ID: <1991Apr11.022531.16242@convex.com> Date: 11 Apr 91 02:25:31 GMT References: <17524@venera.isi.edu> Sender: usenet@convex.com (news access account) Reply-To: tchrist@convex.COM (Tom Christiansen) Distribution: comp Organization: CONVEX Software Development, Richardson, TX Lines: 57 Nntp-Posting-Host: pixel.convex.com From the keyboard of jas@ISI.EDU (Jeff Sullivan): : :I have an situation where I'm storing a "structure" of information :about various files in a SPLITtable string using an associative array. :For example: : :$Images{"TEST.IMG"} = "120#55#4#GIF" : :which might mean that the file TEST.IMG is 120x55 pixels, 4 bitplanes :deep, and is a GIF format file. : :What I want to do is write a sort routine that lets me sort the :%Images elements by image length or width. Here's what I have: : :sub bylen { : :local ($alen, $awid, $adep, $afmt, $blen, $bwid, $bdep, $bfmt); : : ($alen, $awid, $adep, $afmt) = split('#', $Images{$a}); : ($blen, $bwid, $bdep, $bfmt) = split('#', $Images{$b}); : : $alen cmp $blen; : :} : : :However, when I try to do this (on MS-PERL PL 18), I get a syntax :error at the line containing "$alen cmp $blen;" : :Why? Because you're running PL 18. The cmp operator wasn't in the language then. You could use ($alen - $blen) instead of ($alen cmp $blen). :Can't I do this? Is there a better way? Yes: only run one split per element, instead of two per compare. Something like this (untested): sub sort_by_len { &sort_by_field(*Images, $[); } sub sort_by_wid { &sort_by_field(*Images, $[+1); } sub bynum { $a - $b; } sub sort_by_field { local(*table, $field) = @_; local($_, @keys); for (keys %table) { push(@keys, (split(/#/, $table{$_}))[$field]); } sort bynum @keys; } @Images{&sort_by_len} is all the elements in length order; @Images{&sort_by_wid} is all the elements in width order. --tom