Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Well, it got to be that for a web interface, I needed to generate tons of tables, where the user could re-sort lists based on values they click on, and that the values stack up (but other configuration options could cause them to change the order, reverse, etc.). Rather than deal with static (or poorly dynamic) sort routines, here's to constructing expressions for sort() on-the-fly.

The data retrieved from the DB is stored in a 2-d hash with each top-level key being the record #, and having keys that represent 'columns' of data below each of those. So, with that in mind -- here's the (simple) solution to doing dynamic sorts on column-based data. A sub that accepts the columns to sort by, in order, as an arrayref, and then constructs the expression for sort, then executes it for you.

sub is_num_col { # do something to look up whether or not # a given column is numeric or # alphabetic. I use a hash for lookup, # e.g.: return($hash{"$_[0]"}); # # should return 1 if the column is # numeric, 0 otherwise. } sub sort_hash { # this sub creates a sort expression on-the-fly # given an array reference containing the keys # (column names) to sort a 2-d hash by. The 2-d # hash should be provided by reference as the second # argument to the sub. # # The 2-d hash model is used in that the first # dimension referrs to a record (or row), and the second # dimension to the columns within that record. # # An array reference is returned, where each element # is a key from hashref, in the order returned from the sort # # If you wish to reverse the sort order (descending) for # a column/key, simply add 'r-' to the column name. # # example: # # my $aRef = sort_hash(['id','r-name','type'],\%hash); # # Where it will first sort the hash by the id key, then # (descending) by the name key, and then by the type key. my $aRef = shift; my $hRef = shift; die("[sort_hash] Not enough Arguments!\n") if(!defined($aRef) || !def +ined($hRef)); die("[sort_hash] Incorrect Arguments!\n") if(ref($aRef) ne 'ARRAY' || + ref($hRef) ne 'HASH'); my @tests; foreach my $column (@{ $aRef }) { next if(!defined($column)); my $rev = 0; if($column =~ /^r-(.*)$/) { $rev = 1; $column = $1; } if( is_num_col($column) ) { # if this is a numeric column... if($rev == 1) { # descending push(@tests,"\$hRef->{\"\$b\"}{'$column'} <=> \$hRef->{\"\ +$a\"}{'$column'}"); } else { #ascending push(@tests,"\$hRef->{\"\$a\"}{'$column'} <=> \$hRef-> +{\"\$b\"}{'$column'}"); } } else { # if this is an alphabetic column... if($rev == 1) { # descending push(@tests,"\$hRef->{\"\$b\"}{'$column'} cmp \$hRef-> +{\"\$a\"}{'$column'}"); } else { #ascending push(@tests,"\$hRef->{\"\$a\"}{'$column'} cmp \$hR +ef->{\"\$b\"}{'$column'}"); } } } #end foreach # now, create our actual expression via join... my $sort_expr = join(' || ',@tests); # we create an anonymous subref, as doing an eval inside of # the sort's BLOCK can occaisonally cause problems, especially # nested way down in some module. my $SortSub = sub { return(eval $sort_expr); }; my @sorted = sort { &$SortSub } keys(%{ $hRef }); return(\@sorted); }

In reply to Generate Dynamic Sort Expressions by lofichurch

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2024-04-25 08:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found