in reply to Convert Week Of Year to Date
First, your hash keys make it difficult to sort on them chronologically which presumably you would want to do:
If you can, it would be better to use a ISO date string that can be sorted and will only require conversion one time and not every time you need to print results:for my $week ( map { $_->[0] } sort { $a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] } map { [$_, split /\./] } keys %IssuesByWeek ) { # ... }
If you can't do that, then perhaps you could change your data structure to something like $data{year}{week}{issue} = $count; then it will be much easier sorting.for my $key ( keys %IssuesByWeek ) { # New key in format of YYYY-MM-DD $IssuesByWeek{ get_sunday( $key ) } = delete $IssuesByWeek{ $key } +; }
The second thing is that it is generally a waste to sort a list to find the top or bottom of the list. There are routines known as water-mark algorithms that do this much more efficiently. Instead of sorting the entire list and then throwing away most of the work, I would suggest using something similar to:
Note that the commented splice will effectively do the same thing as the array slice. Depending on the size of the array, it may or may not be more efficient.#!/usr/bin/perl use strict; use warnings; my @list = map { int(rand 1000) + 1 } 1 .. 50; print "Top 5:\n"; print "\t$_\n" for top_x(\@list, 5); sub top_x { my ($list, $x) = @_; $x--; my @top; $#top = $x; for my $item ( @$list ) { next if defined $top[ -1 ] && $item <= $top[ -1 ]; for my $id ( 0 .. $#top ) { $top[ $id ] = $item and last if ! defined $top[ $id ]; if ( $item > $top[ $id ] ) { @top[ $id .. $#top ] = ($item, @top[ $id .. $#top - 1] +); #splice(@top, $id, 0, $item), pop @top; last; } } } return @top; }
Cheers - L~R
|
---|