Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
package Sort::LOH; use strict; use Carp; use vars qw($VERSION); $VERSION = '0.01'; ###################################################################### +##### # D O C U M E N T A T I O N =head1 NAME Sort::LOH - Sorter for List of Hashes =head1 SYNOPSIS use strict; use Sort::LOH; my @SAMPLE_DATA = ( {F1 => "1", F2 => "2", F3 => "3", FLOAT => "2", ST => "123 Main Street"}, {F1 => "2", F2 => "3", F3 => "4", FLOAT => "9", ST => "45 Main Street",}, {F1 => "3", F2 => "4", F3 => "4", FLOAT => "045", ST => "2459 Main St"}, {F1 => "4", F2 => "5", F3 => "6", FLOAT => "1.3", ST => "2580 Main Street"}, {F1 => "5", F2 => "6", F3 => "7", FLOAT => "9", ST => "39 Main Street"}, {F1 => "6", F2 => "7", F3 => "8", FLOAT => "8.8", ST => "1888 Main Street"} ); my $sorter = Sort::LOH->new(\@LOH); my @sorted = $sorter->sortMe(["F3", "ST"]); Sorting in reverse order: my @sorted = $sorter->sortMe(["-F3", "-ST"]); Sorting numerically, as opposed to the default alphabetical: my @sorted = $sorter->sortMe(["FLOAT n"]); =head1 DESCRIPTION Takes in a LOH (List of Hashes) and an array of keys to sort by and returns a new, sorted LOH. This module closely relates to Sort::Fields in terms of it's interface how it does things. On of it's main differences is that it is OO, so one can create a Sort::LOH object and perform multiple sorts on it. =cut =head1 PUBLIC METHODS =cut # D O C U M E N T A T I O N ###################################################################### +##### ###################################################################### +##### # C O N S T R U C T O R =head2 new(\@LOH_to_sort) The class constructor. To create a Sort::LOH object, simply call: my $sorter = Sort::LOH->new(\@LOH); =cut sub new { my $class = shift; my $self = {}; bless $self, $class; unless (ref($self->{LOH} = shift) eq 'ARRAY') { croak 'LOH needs a reference to a List of Hashes'; } $self->{SORT_BY} = undef; return $self; } # C O N S T R U C T O R ###################################################################### +##### ###################################################################### +##### # S T A T I C M E T H O D S =head2 element_class() The name of the class for use in calling methods. This is a trick to simplify inheritance of static factory methods that I got from Perlmon +ks: http://www.perlmonks.org/index.pl?node_id=74924 Inheriting classes wou +ld create override element_class with the name of their class. =cut sub element_class { return "Sort::LOH"; } =head2 static(@sort_by, \@LOH_to_sort) A static method that allows caller to make the class do all the work with one swell foop: my @sorted = Sort::LOH->static(["F1", "F2"], \@SAMPLE_DATA); as opposed to my $sorter = Sort::LOH->new(\@LOH); my @sorted = $sorter->sortMe(["F1", "F2"]); If caller wants to do multiple sorts, one should use the constructor, +and create a Sort::LOH object, since then one only has to pass in the data + once: my $sorter = Sort::LOH->new(\@LOH); my @sorted = $sorter->sortMe(["F1", "F2"]); my @revSort = $sorter->sortMe(["-F1", "-F2"]); =cut sub static { my $self = shift; my @sortby = shift || croak 'USAGE: Sort::LOH->factory(@LIST, \@L +OH)'; my @loh = shift || croak 'Sort::LOH::factory() needs 2 args'; my $sorter = $self->element_class()->new(@loh); return $sorter->sortMe(@sortby); } # S T A T I C M E T H O D S ###################################################################### +##### ###################################################################### +##### # C L A S S M E T H O D S =head2 sortMe(@sort_by) The workhorse of this class. Expects a list of the LOH keys to determi +ne the sort order for the returned LOH. my @sorted = $sorter->sortMe(["F1", "F2"]); It is possible to do a reverse sort for a particular key by placing a +minus sign at the front of it: my @sorted = $sorter->sortMe(["-F1", "-F2"]); If one wants to do a numeric sort, instead of a alphabetical sort, pla +ce " n" after the key in the list: my @sorted = $sorter->sortMe(["F1 n", "F2 n"]); =cut sub sortMe { my $self = shift; $self->{SORT_BY} = shift || croak 'LOH needs a list of fields to s +ort by'; my (@sortcode, @sortedLOH); for (@{$self->{SORT_BY}}) { unless (/^-?\w+\s*n?$/) { croak "improperly formatted sort column specifier '$_'"; } # Logic from Sort::Fields # Set a and b depending on '-' flag at the start of a key my ($a, $b) = /^-/ ? qw(b a) : qw(a b); # Is it a string or numeric sort? my $op = /\s+n$/ ? '<=>' : 'cmp'; # Get the actual column name my ($col) = /^-?(\w+)/; # Make sure that the sort key being passed in exists. if (exists($self->{LOH}[0]{$col})) { push @sortcode, "\$${a}->{${col}} $op \$${b}->{${col}}"; } } # Croak if there were no valid sort keys specified. unless ($sortcode[0]) { croak "No valid key match to sort LOH."; } my $sortcode = join " or ", @sortcode; $sortcode = "sort { $sortcode } \@{\$self->{LOH}};"; @sortedLOH = eval "$sortcode"; if ($@) { croak "Sort Failure of LOH\n$@"; } return @sortedLOH; } # C L A S S M E T H O D S ###################################################################### +##### 1; __END__ =head1 BUGS =over =item * When a LOH is passed in that has a key that isn't present in each row in the list, and the class is sorted on that key, sort will print out errors for comparing with undefined values. For instance: my @the_data = ( {ID => "a", CITY => "f1 f"}, {ID => "b", CITY => "f2 a"}, {ID => "c"}, {ID => "f", CITY => "f6 e"} ); my $lohSorter = Sort::LOH->new(\@the_data); my @sorted = $lohSorter->sortMe(["CITY"]); Making sure that each key has an empty string as a defined value will solve this: my @better_data = ( {ID => "a", CITY => "f1 f"}, {ID => "b", CITY => "f2 a"}, {ID => "c", CITY => ""}, {ID => "f", CITY => "f6 e"} ); I haven't figured out a way to trap this error as of yet. =back =head1 SUPPORT The author always welcomes your comments, critiques, suggestions or requests. =head1 AUTHOR Christopher Baker <ignatz@ignatzmouse.com> http://www.ignatzmouse.com =head1 COPYRIGHT Copyright (c) 2002 Christopher Baker. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =head1 SEE ALSO Sort::File, Data::Table =cut

In reply to Sort::LOH by ignatz

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 drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2024-04-19 16:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found