Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Sorting based on string value

Reply
Thread Tools

Sorting based on string value

 
 
Ninja67
Guest
Posts: n/a
 
      12-04-2006
I've got the following code in a script:

my $cost_order = "A2yB";
my @series_cost = ();

for (@{$struct->{tree}->[0]->{rectangle}}) {
my $rec_string = "<table><tr><td ";
$rec_string .= ' meascode="'.$_->{meascode}.'"></td></tr></table>';

SWITCH: {
if ($_->{datafile} =~ /^cost/) { push(@series_cost, $rec_string);
last SWITCH; }
$nothing = 1;
}
}

Now that I have my array filled, I want to sort the contents of each
array by the "meascode" attribute. Each meascode attribute is a single
character that matches one of the characters in the $cost_order string.
How can I sort an array based on the order of the characters in the
$cost_order string?

So my array might contain:
<table><tr><td meascode="y"></td></tr></table>
<table><tr><td meascode="2"></td></tr></table>
<table><tr><td meascode="A"></td></tr></table>
<table><tr><td meascode="B"></td></tr></table>

but I need it to contain:
<table><tr><td meascode="A"></td></tr></table>
<table><tr><td meascode="2"></td></tr></table>
<table><tr><td meascode="y"></td></tr></table>
<table><tr><td meascode="B"></td></tr></table>

Thanks!

 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      12-04-2006
Ninja67 wrote:
> I've got the following code in a script:
>
> my $cost_order = "A2yB";
> my @series_cost = ();
>
> for (@{$struct->{tree}->[0]->{rectangle}}) {
> my $rec_string = "<table><tr><td ";
> $rec_string .= ' meascode="'.$_->{meascode}.'"></td></tr></table>';
>
> SWITCH: {
> if ($_->{datafile} =~ /^cost/) { push(@series_cost, $rec_string);
> last SWITCH; }
> $nothing = 1;
> }
> }
>
> Now that I have my array filled, I want to sort the contents of each
> array by the "meascode" attribute. Each meascode attribute is a single
> character that matches one of the characters in the $cost_order string.
> How can I sort an array based on the order of the characters in the
> $cost_order string?
>
> So my array might contain:
> <table><tr><td meascode="y"></td></tr></table>
> <table><tr><td meascode="2"></td></tr></table>
> <table><tr><td meascode="A"></td></tr></table>
> <table><tr><td meascode="B"></td></tr></table>
>
> but I need it to contain:
> <table><tr><td meascode="A"></td></tr></table>
> <table><tr><td meascode="2"></td></tr></table>
> <table><tr><td meascode="y"></td></tr></table>
> <table><tr><td meascode="B"></td></tr></table>


Maybe I'm not understanding your goal, but why aren't you just sorting
the values in your original array, before looping through them and
putting them inside strings in a new array? Why would you want to fill
the array, convoluting your value, then have to loop back through that
string, parse out the data you just put in, so that you can compare it?

Change:
> for (@{$struct->{tree}->[0]->{rectangle}}) {

To:
for (sort { $a->{meascode} cmp $b->{meascode} }
@{$struct->{tree}->[0]->{rectangle}}) {

Paul Lalli

 
Reply With Quote
 
 
 
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      12-05-2006
Ninja67 wrote:
> Now that I have my array filled, I want to sort the contents of each
> array by the "meascode" attribute. Each meascode attribute is a single
> character that matches one of the characters in the $cost_order string.
> How can I sort an array based on the order of the characters in the
> $cost_order string?


One way:

my @series_cost = (
'<table><tr><td meascode="y"></td></tr></table>',
'<table><tr><td meascode="2"></td></tr></table>',
'<table><tr><td meascode="A"></td></tr></table>',
'<table><tr><td meascode="B"></td></tr></table>'
);

my $cost_order = 'A2yB';

my @sorted;
while ( my $mc = chop $cost_order ) {
unshift @sorted, grep /code="$mc"/, @series_cost;
}

print map "$_\n", @sorted;

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
Mumia W. (reading news)
Guest
Posts: n/a
 
      12-05-2006
On 12/04/2006 04:46 PM, Ninja67 wrote:
> I've got the following code in a script:
>
> my $cost_order = "A2yB";
> my @series_cost = ();
>
> for (@{$struct->{tree}->[0]->{rectangle}}) {
> my $rec_string = "<table><tr><td ";
> $rec_string .= ' meascode="'.$_->{meascode}.'"></td></tr></table>';
>
> SWITCH: {
> if ($_->{datafile} =~ /^cost/) { push(@series_cost, $rec_string);
> last SWITCH; }
> $nothing = 1;
> }
> }
>
> Now that I have my array filled, I want to sort the contents of each
> array by the "meascode" attribute. Each meascode attribute is a single
> character that matches one of the characters in the $cost_order string.
> How can I sort an array based on the order of the characters in the
> $cost_order string?
>
> So my array might contain:
> <table><tr><td meascode="y"></td></tr></table>
> <table><tr><td meascode="2"></td></tr></table>
> <table><tr><td meascode="A"></td></tr></table>
> <table><tr><td meascode="B"></td></tr></table>
>
> but I need it to contain:
> <table><tr><td meascode="A"></td></tr></table>
> <table><tr><td meascode="2"></td></tr></table>
> <table><tr><td meascode="y"></td></tr></table>
> <table><tr><td meascode="B"></td></tr></table>
>
> Thanks!
>


Use a hash table to store the values of y2AB and use that hash table to
help the sort comparison routine:

use strict;
use warnings;
use Data:umper;

my $count = 0;
my %cost_order = map +($_, $count++), qw(A 2 y B);
my @ms = map { meascode => $_ }, qw(y B 2 A);
my @series_cost = ();

for (@ms) {
my $rec_string = "<table><tr><td meascode='$_->{meascode}'>"
. " </td></tr></table>\n";
push @series_cost, $rec_string;
}

my @sorted = sort {
my @vals = "$a $b" =~ /meascode='([^']+)'/g;
$cost_order{$vals[0]} cmp $cost_order{$vals[1]};
} @series_cost;
print Dumper(\@sorted);



--
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Mumia W. (reading news)
Guest
Posts: n/a
 
      12-05-2006
On 12/04/2006 07:49 PM, Gunnar Hjalmarsson wrote:
> Ninja67 wrote:
>> Now that I have my array filled, I want to sort the contents of each
>> array by the "meascode" attribute. Each meascode attribute is a single
>> character that matches one of the characters in the $cost_order string.
>> How can I sort an array based on the order of the characters in the
>> $cost_order string?

>
> One way:
>
> my @series_cost = (
> '<table><tr><td meascode="y"></td></tr></table>',
> '<table><tr><td meascode="2"></td></tr></table>',
> '<table><tr><td meascode="A"></td></tr></table>',
> '<table><tr><td meascode="B"></td></tr></table>'
> );
>
> my $cost_order = 'A2yB';
>
> my @sorted;
> while ( my $mc = chop $cost_order ) {
> unshift @sorted, grep /code="$mc"/, @series_cost;
> }
>
> print map "$_\n", @sorted;
>


That's pretty cool. I almost wish I hadn't posted my own solution

It took me a couple of minutes to figure it out because the 'sort'
function appears nowhere in the code. It's an insertion sort, and it
uses the $cost_order without creating an external hash or anything, and
it takes three lines--pretty good.


--
(E-Mail Removed)
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      12-05-2006
>>>>> "MW(n" == Mumia W (reading news) <(E-Mail Removed)> writes:

>> my @series_cost = (
>> '<table><tr><td meascode="y"></td></tr></table>',
>> '<table><tr><td meascode="2"></td></tr></table>',
>> '<table><tr><td meascode="A"></td></tr></table>',
>> '<table><tr><td meascode="B"></td></tr></table>'


>> my $cost_order = 'A2yB';
>> my @sorted;
>> while ( my $mc = chop $cost_order ) {
>> unshift @sorted, grep /code="$mc"/, @series_cost;
>> }


MW(n> That's pretty cool. I almost wish I hadn't posted my own solution

MW(n> It took me a couple of minutes to figure it out because the 'sort'
MW(n> function appears nowhere in the code. It's an insertion sort, and it
MW(n> uses the $cost_order without creating an external hash or anything,
MW(n> and it takes three lines--pretty good.

and an insertion (or bubble) sort runs in O( N ** 2 ) which is very slow
for larger input lists.

given the above you can do this (tested):

use Sort::Maker ;

my @unsorted = (

'<table><tr><td meascode="y"></td></tr></table>',
'<table><tr><td meascode="2"></td></tr></table>',
'<table><tr><td meascode="A"></td></tr></table>',
'<table><tr><td meascode="B"></td></tr></table>',
) ;


my $sorter = make_sorter( 'GRT', string => qr/"(\w+)"/ ) ;
$sorter or die $@ ;

print map "$_\n", $sorter->( @unsorted ) ;


i agree that it would be better to sort the strings before adding the
html cruft but you can easily extract the key out of those strings with
a simple regex.

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      12-05-2006
Uri Guttman wrote:
>>>>>>"MW(n" == Mumia W (reading news) writes:

>
> >> my @series_cost = (
> >> '<table><tr><td meascode="y"></td></tr></table>',
> >> '<table><tr><td meascode="2"></td></tr></table>',
> >> '<table><tr><td meascode="A"></td></tr></table>',
> >> '<table><tr><td meascode="B"></td></tr></table>'

>
> >> my $cost_order = 'A2yB';
> >> my @sorted;
> >> while ( my $mc = chop $cost_order ) {
> >> unshift @sorted, grep /code="$mc"/, @series_cost;
> >> }

>
> MW(n> That's pretty cool. I almost wish I hadn't posted my own solution
>
> MW(n> It took me a couple of minutes to figure it out because the 'sort'
> MW(n> function appears nowhere in the code. It's an insertion sort, and it
> MW(n> uses the $cost_order without creating an external hash or anything,
> MW(n> and it takes three lines--pretty good.
>
> and an insertion (or bubble) sort runs in O( N ** 2 ) which is very slow
> for larger input lists.


Yep, it's not recommended for larger lists.

> given the above you can do this (tested):
>
> use Sort::Maker ;
>
> my @unsorted = (
>
> '<table><tr><td meascode="y"></td></tr></table>',
> '<table><tr><td meascode="2"></td></tr></table>',
> '<table><tr><td meascode="A"></td></tr></table>',
> '<table><tr><td meascode="B"></td></tr></table>',
> ) ;
>
>
> my $sorter = make_sorter( 'GRT', string => qr/"(\w+)"/ ) ;
> $sorter or die $@ ;
>
> print map "$_\n", $sorter->( @unsorted ) ;


That's an efficient solution, but not to the OP's problem.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
Ninja67
Guest
Posts: n/a
 
      12-05-2006

Gunnar Hjalmarsson wrote:
> Ninja67 wrote:
> > Now that I have my array filled, I want to sort the contents of each
> > array by the "meascode" attribute. Each meascode attribute is a single
> > character that matches one of the characters in the $cost_order string.
> > How can I sort an array based on the order of the characters in the
> > $cost_order string?

>
> One way:
>
> my @series_cost = (
> '<table><tr><td meascode="y"></td></tr></table>',
> '<table><tr><td meascode="2"></td></tr></table>',
> '<table><tr><td meascode="A"></td></tr></table>',
> '<table><tr><td meascode="B"></td></tr></table>'
> );
>
> my $cost_order = 'A2yB';
>
> my @sorted;
> while ( my $mc = chop $cost_order ) {
> unshift @sorted, grep /code="$mc"/, @series_cost;
> }
>
> print map "$_\n", @sorted;
>
> --
> Gunnar Hjalmarsson
> Email: http://www.gunnar.cc/cgi-bin/contact.pl


You rock! That's awesome.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
sorting map value based Philipp Kraus C++ 6 11-07-2010 04:55 PM
sorting string array based on delimiter padmagvs Java 1 08-15-2010 11:21 PM
Sorting keys of hash based on value Aldric Giacomoni Ruby 4 03-22-2010 08:35 PM
Howto identify a string value vs. a numeric value in std::string frohlinger@gmail.com C++ 9 09-19-2007 09:34 AM
Sorting a hash table based on value (not key) vikas C Programming 3 08-16-2007 12:53 PM



Advertisments