Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help with array/hash sorting

2 views
Skip to first unread message

Saya

unread,
May 3, 2006, 3:10:08 AM5/3/06
to
Hi,

I have a function as shown below:

sub HTMLCell {

my $test = @arrGenFiles;
my $i;

for($i=0; $i < $test;$i++){

$hashUserMods{$arrGenFiles[$i]->{modUser}}++;
print "<tr>";

if ($arrGenFiles[$i]->{modStatus} eq "OkDate"){
print "<td align=\"center\"><img
src=\"$URLAppend/iw/performance_tools/dot-green.gif\"/></td>";
}
else {
print "<td align=\"center\"><img
src=\"$URLAppend/iw/performance_tools/dot-red.gif\"/></td>";
}

print "<td><a href=\"" . $arrGenFiles[$i]->{fileURL} . "\"
target=\"_blank\">" . $arrGenFiles[$i]->{fileName} . "</a><br>" .
$arrGenFiles[$i]->{filePath} . "</td>";
print "<td>" . $arrGenFiles[$i]->{modDate} . "</td>";
print "<td>" . $arrGenFiles[$i]->{modUser} . "</td>";
print "</tr>";
}

}

Now I want the output of the html to be sorted on the {modDate} so that
the oldest date come first.

Any help/clue on how to achieve this will be greatly appreciated.

Regards
Saya

use...@davidfilmer.com

unread,
May 3, 2006, 4:10:09 AM5/3/06
to
Saya wrote:
> Now I want the output of the html to be sorted on the {modDate} so that
> the oldest date come first.

OK, this works. But I HATE this. I DESPISE this. This "solution"
creates a secondary data structure which is a subset of the primary
data structure. That goes against EVERY grain of whatever programming
instinct I have. But I could not figure out how to do it without the
secondary structure. The ONLY reason that I post this crummy code is
in hope that someone smarter than I will come along and educate us
both.

Here's the sample CRUMMY code which will do what you ask:

#!/usr/bin/perl
use strict; use warnings;

my @data = ( #build some sample data
{'mod_date' => '2005-06-01', 'mod_user' => 'fred' },
{'mod_date' => '2005-01-07', 'mod_user' => 'barney'},
{'mod_date' => '2005-09-14', 'mod_user' => 'wilma' },
);

my %index; #OH NO! Not a data substructure! Say it isn't so!
$index{$data[$_]{'mod_date'}} = $_ for 0..$#data; #it BURNS us!

foreach my $date(sort keys %index) { #not that substructure AGAIN
printf "<tr><td>%s</td><td>%s</td></tr>\n",
$data[$index{$date}]{'mod_date'},
$data[$index{$date}]{'mod_user'};
}

__END__

But only use this as a last resort. Wait a bit and see if a smart
person responds.

--
http://DavidFilmer.com

DJ Stunks

unread,
May 3, 2006, 11:37:30 AM5/3/06
to

Well, I really wasn't going to reply to this because your code is
pretty gross (no offence), and you didn't give any sample data (so I
have no idea if my solution will work) but since David took a crack at
trying to figure out what you're getting at I figured I should too.

Here's what I came up with. I use ST to make the sort more efficient,
but if your array isn't large you could just sort on time (date)
directly.

HTH,
-jp

sub HTMLCell {
use Date::Parse;
use CGI qw{ :standard };

my @sortedFiles
= map { $_->[0] }
sort { $b->[1] <=> $a->[1] }
map { [ $_, str2time( $_->{modDate} ) ] }
@arrGenFiles;

for my $file (@sortedFiles){

$hashUserMods{$file->{modUser}}++;

my $dot_gif = $file->{modStatus} eq 'OkDate' ? 'dot-green.gif'
: 'dot-red.gif'
;

print Tr(
td({-align => 'center'},
img({src => "$URLAppend/iw/performance_tools/$dot_gif"})
),

td(
a({href => $file->{fileURL}, target => "_blank",},
$file->{fileName}
)
),

td(
$file->{modDate}
),

td(
$file->{modUser}
),
);
}
}

use...@davidfilmer.com

unread,
May 3, 2006, 1:45:00 PM5/3/06
to
DJ Stunks wrote:
> [Better Code than I wrote]

Ah, fresh air! I reworked my sample code to use the sorting technique
that jp pointed out (thanks - that was really bugging me!); here it is
without the dreaded data substructure:

#!/usr/bin/perl
use strict; use warnings;

use HTTP::Date;

my @data = ( #build some sample data
{'mod_date' => '2005-06-01', 'mod_user' => 'fred' },
{'mod_date' => '2005-01-07', 'mod_user' => 'barney'},
{'mod_date' => '2005-09-14', 'mod_user' => 'wilma' },
);

printf "<tr><td>%s</td><td>%s</td></tr>\n",
$_->{'mod_date'},
$_->{'mod_user'}
for reverse


map { $_->[0] }
sort { $b->[1] <=> $a->[1] }

map { [ $_, str2time( $_->{mod_date} ) ] }
@data;

__END__

--
http://DavidFilmer.com

DJ Stunks

unread,
May 3, 2006, 2:29:33 PM5/3/06
to

use...@DavidFilmer.com wrote:
> printf "<tr><td>%s</td><td>%s</td></tr>\n",
> $_->{'mod_date'},
> $_->{'mod_user'}
> for reverse
> map { $_->[0] }
> sort { $b->[1] <=> $a->[1] }
> map { [ $_, str2time( $_->{mod_date} ) ] }
> @data;

I wondered why you were reversing the sort, until I realized I had $b
<=> $a in my code. (which was a typo).

Switch it to $a->[1] <=> $b->[1] and you eliminate the need to reverse.


Why'd you pick HTTP::Date vs Date::Parse? One should benchmark both
modules... :P

-jp

use...@davidfilmer.com

unread,
May 3, 2006, 3:25:56 PM5/3/06
to
DJ Stunks wrote:

> Switch it to $a->[1] <=> $b->[1] and you eliminate the need to reverse.

Ah, that would be better, yes.

> Why'd you pick HTTP::Date vs Date::Parse?

I have a VERY, VERY good reason why I did that... when I looked on CPAN
for the str2time method (because I didn't remember what provides it),
HTTP::Date was the first module that popped up. (OK, so maybe that's
not really such a good reason)

--
http://DavidFilmer.com

Uri Guttman

unread,
May 3, 2006, 6:36:19 PM5/3/06
to
>>>>> "DS" == DJ Stunks <DJSt...@gmail.com> writes:

DS> use...@DavidFilmer.com wrote:
>> printf "<tr><td>%s</td><td>%s</td></tr>\n",
>> $_->{'mod_date'},
>> $_->{'mod_user'}
>> for reverse
>> map { $_->[0] }
>> sort { $b->[1] <=> $a->[1] }
>> map { [ $_, str2time( $_->{mod_date} ) ] }
>> @data;

DS> I wondered why you were reversing the sort, until I realized I had $b
DS> <=> $a in my code. (which was a typo).

DS> Switch it to $a->[1] <=> $b->[1] and you eliminate the need to reverse.

and if you used Sort::Maker you wouldn't have those $a vs $b typos as
you only have one copy of the key extraction code. and the same goes for
not worrying about [1] or such.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

use...@davidfilmer.com

unread,
May 3, 2006, 9:36:13 PM5/3/06
to
Uri Guttman wrote:

> and if you used Sort::Maker...

When I read Perl Best Practices I said to myself, "I gotta check out
Sort::Maker," but then I forgot those good intentions. Thanks for
reminding me!

However, in following up on those intentions, I ran into some trouble
implementing the example from Damian's book. So I opened a new thread
(as it is getting a bit OT for this discussion). If you would care to
comment, the thread is in CLPMisc (http://tinyurl.com/j4hzg), and I
would welcome your input, as you are, obviously, the foremost expert in
Sort::Maker (since you WROTE it).

--
http://DavidFilmer.com

Uri Guttman

unread,
May 4, 2006, 12:14:17 AM5/4/06
to
>>>>> "u" == usenet <use...@DavidFilmer.com> writes:

u> Uri Guttman wrote:
>> and if you used Sort::Maker...

u> When I read Perl Best Practices I said to myself, "I gotta check out
u> Sort::Maker," but then I forgot those good intentions. Thanks for
u> reminding me!

u> However, in following up on those intentions, I ran into some trouble
u> implementing the example from Damian's book. So I opened a new thread
u> (as it is getting a bit OT for this discussion). If you would care to
u> comment, the thread is in CLPMisc (http://tinyurl.com/j4hzg), and I
u> would welcome your input, as you are, obviously, the foremost expert in
u> Sort::Maker (since you WROTE it).

posted a reply in .misc. there was a (since fixed) bug in the module but
the book error wasn't caught.

0 new messages