Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Sorting array of hash references

Reply
Thread Tools

Sorting array of hash references

 
 
alwaysonnet
Guest
Posts: n/a
 
      10-26-2006
hi all,

I've got an array of hash-references as following. ( i've represented
hash-references as a table below)


Type A/C No Status(active/inactive)

Prefund 12345 Y
Prefund 45678 N
Receipt 78878 N
Receipt 32365 Y
Payment 56546 N
Payment 23456 N
Payment 34093 Y

I want to display all the active accounts (status with "Y") before
inactive accounts along with preserving the order by type ie., Prefund
should come first before Receipt and Payment along the order.

I've got the code which i've hard-coded the account type(Payment) and
then sorting according to their status.

foreach my $label(@accts) {
if ($label->{'batype'} eq "Payment") {
push(@acct_pay,$label);
}
}
foreach $x(@acct_pay) {
@sorted = sort { $b->{'baactive'} cmp $a->{'baactive'} } @acct_pay;
}

Is there any way of how to achieve this by sorting according to status
by preserving the account type order.

Thanks a ton,
Raj

 
Reply With Quote
 
 
 
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      10-26-2006
alwaysonnet <> wrote in comp.lang.perl.misc:
> hi all,
>
> I've got an array of hash-references as following. ( i've represented
> hash-references as a table below)


It would have been *much* better to present Perl code that produces
the array of hashes instead of a table that leaves us guessing how
your data relate to your code.

> Type A/C No Status(active/inactive)
>
> Prefund 12345 Y
> Prefund 45678 N
> Receipt 78878 N
> Receipt 32365 Y
> Payment 56546 N
> Payment 23456 N
> Payment 34093 Y
>
> I want to display all the active accounts (status with "Y") before
> inactive accounts along with preserving the order by type ie., Prefund
> should come first before Receipt and Payment along the order.


Unless you're running a rather old version of Perl, Perl's sort() is
stable, meaning the original order is preserved when elements compare
equal. If you simply sort by status the result should be what you
want.

> I've got the code which i've hard-coded the account type(Payment) and
> then sorting according to their status.
>
> foreach my $label(@accts) {
> if ($label->{'batype'} eq "Payment") {


Is "batype" what appears in the column "Type"? Is "baactive" what
appears in column "Status(active/inactive)"? Please make explicit
what is what, don't let your readers guess.

> push(@acct_pay,$label);
> }
> }
> foreach $x(@acct_pay) {
> @sorted = sort { $b->{'baactive'} cmp $a->{'baactive'} } @acct_pay;
> }
>
> Is there any way of how to achieve this by sorting according to status
> by preserving the account type order.


That will only show the three "Payment" records. What does it have to
do with your question?

Anno
 
Reply With Quote
 
 
 
 
alwaysonnet
Guest
Posts: n/a
 
      10-26-2006
hi ,

"batype" refers to column "Type" , "baactive" refers to column
"Status(active/inactive)"?

anno, You're correct that the code will show only 3 records of
"Payment" type as I have put a condition like "if ($label->{'batype'}
eq "Payment") ".

I need to preserve the actual order of "Type" but for each "Type" i
need to sort with their active accounts.

Raj


wrote:
> alwaysonnet <> wrote in comp.lang.perl.misc:
> > hi all,
> >
> > I've got an array of hash-references as following. ( i've represented
> > hash-references as a table below)

>
> It would have been *much* better to present Perl code that produces
> the array of hashes instead of a table that leaves us guessing how
> your data relate to your code.
>
> > Type A/C No Status(active/inactive)
> >
> > Prefund 12345 Y
> > Prefund 45678 N
> > Receipt 78878 N
> > Receipt 32365 Y
> > Payment 56546 N
> > Payment 23456 N
> > Payment 34093 Y
> >
> > I want to display all the active accounts (status with "Y") before
> > inactive accounts along with preserving the order by type ie., Prefund
> > should come first before Receipt and Payment along the order.

>
> Unless you're running a rather old version of Perl, Perl's sort() is
> stable, meaning the original order is preserved when elements compare
> equal. If you simply sort by status the result should be what you
> want.
>
> > I've got the code which i've hard-coded the account type(Payment) and
> > then sorting according to their status.
> >
> > foreach my $label(@accts) {
> > if ($label->{'batype'} eq "Payment") {

>
> Is "batype" what appears in the column "Type"? Is "baactive" what
> appears in column "Status(active/inactive)"? Please make explicit
> what is what, don't let your readers guess.
>
> > push(@acct_pay,$label);
> > }
> > }
> > foreach $x(@acct_pay) {
> > @sorted = sort { $b->{'baactive'} cmp $a->{'baactive'} } @acct_pay;
> > }
> >
> > Is there any way of how to achieve this by sorting according to status
> > by preserving the account type order.

>
> That will only show the three "Payment" records. What does it have to
> do with your question?
>
> Anno


 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      10-26-2006
alwaysonnet <> wrote in comp.lang.perl.misc:
> hi ,
>
> "batype" refers to column "Type" , "baactive" refers to column
> "Status(active/inactive)"?
>
> anno, You're correct that the code will show only 3 records of
> "Payment" type as I have put a condition like "if ($label->{'batype'}
> eq "Payment") ".
>
> I need to preserve the actual order of "Type" but for each "Type" i
> need to sort with their active accounts.


[Tofu snipped. Don't do that]

So just sort by "baactive", your records are already sorted by "batype".
As I said in my previous reply, Perl's sort is stable unless you have
an old version of Perl.

Anno
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      10-26-2006
alwaysonnet <> wrote:


> I've got an array of hash-references as following.



If you say so, but those are some mighty cumbersome keys...


> ( i've represented
> hash-references as a table below)



Why have you done that rather than representing them in real Perl
code that an answerer could use to test any potential answers?

If you make the answerer do that extra work, they are likely to move on
to helping some other poster who has taken the time to make it
easier for them to give an accurate answer.

Have you seen the Posting Guidelines that are posted here frequently?


[ snip the table ]


> I want to display all the active accounts (status with "Y") before
> inactive accounts along with preserving the order by type ie., Prefund

^^^^^^^^^^^^^^^^^^^^
> should come first before Receipt and Payment along the order.



Recent perls have a "stable" sort, so you should get that by default.


> if ($label->{'batype'} eq "Payment") {

^^^^^^

That is not the key that you said in the table. Which is it?

Precision is important in programming...


> Is there any way of how to achieve this by sorting according to status
> by preserving the account type order.



Yes, and it is a plain old everyday sort that you should have been
able to get simply by reading the docs about sorting...


----------------------------
#!/usr/bin/perl
use warnings;
use strict;
use Data:umper;

my @records = (
{ 'Type' => 'Prefund', 'A/C No' => 12345, 'Status(active/inactive)' => 'Y' },
{ 'Type' => 'Prefund', 'A/C No' => 45678, 'Status(active/inactive)' => 'N' },
{ 'Type' => 'Receipt', 'A/C No' => 78878, 'Status(active/inactive)' => 'N' },
{ 'Type' => 'Receipt', 'A/C No' => 32365, 'Status(active/inactive)' => 'Y' },
{ 'Type' => 'Payment', 'A/C No' => 56546, 'Status(active/inactive)' => 'N' },
{ 'Type' => 'Payment', 'A/C No' => 23456, 'Status(active/inactive)' => 'N' },
{ 'Type' => 'Payment', 'A/C No' => 34093, 'Status(active/inactive)' => 'Y' },
);

my @sorted = sort { $b->{'Status(active/inactive)'} cmp
$a->{'Status(active/inactive)'}
} @records;

print Dumper \@sorted;
----------------------------


--
Tad McClellan SGML consulting
Perl programming
Fort Worth, Texas
 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      10-26-2006
wrote:
> alwaysonnet <> wrote in comp.lang.perl.misc:
> > hi ,
> >
> > "batype" refers to column "Type" , "baactive" refers to column
> > "Status(active/inactive)"?
> >
> > anno, You're correct that the code will show only 3 records of
> > "Payment" type as I have put a condition like "if ($label->{'batype'}
> > eq "Payment") ".
> >
> > I need to preserve the actual order of "Type" but for each "Type" i
> > need to sort with their active accounts.

>
> [Tofu snipped. Don't do that]
>
> So just sort by "baactive", your records are already sorted by "batype".
> As I said in my previous reply, Perl's sort is stable unless you have
> an old version of Perl.


But that isn't necessarily what he wants. Maybe He wants them sorted
first by type, then by status. Not first by status, but then by type,
which is what stable sort would give him.


my %type_order = qw/Prefund 1 Receipt 2 Payment 3/;

@sorted = sort { $type_order{$a->{'type'}} <=> $type_order{$b->{'type'}}
||
$b->{'baactive'} cmp $a->{'baactive'}
} @acct_pay;

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      10-26-2006
<> wrote in comp.lang.perl.misc:
> wrote:
> > alwaysonnet <> wrote in comp.lang.perl.misc:
> > > hi ,
> > >
> > > "batype" refers to column "Type" , "baactive" refers to column
> > > "Status(active/inactive)"?
> > >
> > > anno, You're correct that the code will show only 3 records of
> > > "Payment" type as I have put a condition like "if ($label->{'batype'}
> > > eq "Payment") ".
> > >
> > > I need to preserve the actual order of "Type" but for each "Type" i
> > > need to sort with their active accounts.

> >
> > [Tofu snipped. Don't do that]
> >
> > So just sort by "baactive", your records are already sorted by "batype".
> > As I said in my previous reply, Perl's sort is stable unless you have
> > an old version of Perl.

>
> But that isn't necessarily what he wants. Maybe He wants them sorted
> first by type, then by status. Not first by status, but then by type,
> which is what stable sort would give him.


I thought of that, but

I want to display all the active accounts (status with "Y") before
inactive accounts...

doesn't leave much doubt that "status" is the primary key.

[nicely formatted two-key sort snipped]

Since the primary key is only two-valued, sort() could be replaced
with two grep()s (untested):

@sorted = (
grep( $_->{ baactive} eq 'Y', @acct_pay),
grep( $_->{ baactive} eq 'N', @acct_pay),
);

Anno
 
Reply With Quote
 
alwaysonnet
Guest
Posts: n/a
 
      10-27-2006
Hi Xho,

The code snippet you've provided really worked out for me.

Thanks,
Raj

 
Reply With Quote
 
alwaysonnet
Guest
Posts: n/a
 
      10-30-2006
hi,

my %type_order = qw/Prefund 1 Receipt 2 Payment 3/;

my @records = (
{ 'Type' => 'Prefund', 'A/C No' => 12345, 'Status(active/inactive)' =>
'Y' },
{ 'Type' => 'Prefund', 'A/C No' => 45678, 'Status(active/inactive)' =>
'N' },
{ 'Type' => 'Receipt', 'A/C No' => 78878, 'Status(active/inactive)' =>
'N' },
{ 'Type' => 'Payment', 'A/C No' => 88888, 'Status(active/inactive)' =>
'Y' },
{ 'Type' => 'Receipt', 'A/C No' => 32365, 'Status(active/inactive)' =>
'Y' },
{ 'Type' => 'Prefund', 'A/C No' => 11111, 'Status(active/inactive)' =>
'N' },
{ 'Type' => 'Payment', 'A/C No' => 56546, 'Status(active/inactive)' =>
'N' },
{ 'Type' => 'Payment', 'A/C No' => 23456, 'Status(active/inactive)' =>
'N' },
{ 'Type' => 'Payment', 'A/C No' => 34093, 'Status(active/inactive)' =>
'Y' },
);

my @sorted = sort { $type_order{$a->{'Type'}} <=>
$type_order{$b->{'Type'}}
||
$b->{'Status(active/inactive)'} cmp
$a->{'Status(active/inactive)'}

} @records;

which is exactly displaying the active records for a particular account
type.

Can further sorting on 'A/C No' so that all the active/inactive records
for a particular account type should be displayed in sorted order.

Ex: In this case for the type "Prefund" a/c no's 45678 and 11111 are
not sorted where their active/inactive status are "N".

Thanks,
Raj

 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      10-30-2006
alwaysonnet <> wrote:
> hi,
>
> my %type_order = qw/Prefund 1 Receipt 2 Payment 3/;
>
> my @records = (
> { 'Type' => 'Prefund', 'A/C No' => 12345, 'Status(active/inactive)' =>
> 'Y' },



That is a horrid choice of Status key.

Q: is the status active or inactive?

A: yes

huh??

'Status active' => 'Y'

or

'Status' => 'active'

would be much better.


> { 'Type' => 'Prefund', 'A/C No' => 45678, 'Status(active/inactive)' =>
> 'N' },
> { 'Type' => 'Receipt', 'A/C No' => 78878, 'Status(active/inactive)' =>
> 'N' },
> { 'Type' => 'Payment', 'A/C No' => 88888, 'Status(active/inactive)' =>
> 'Y' },
> { 'Type' => 'Receipt', 'A/C No' => 32365, 'Status(active/inactive)' =>
> 'Y' },
> { 'Type' => 'Prefund', 'A/C No' => 11111, 'Status(active/inactive)' =>
> 'N' },
> { 'Type' => 'Payment', 'A/C No' => 56546, 'Status(active/inactive)' =>
> 'N' },
> { 'Type' => 'Payment', 'A/C No' => 23456, 'Status(active/inactive)' =>
> 'N' },
> { 'Type' => 'Payment', 'A/C No' => 34093, 'Status(active/inactive)' =>
> 'Y' },
> );
>
> my @sorted = sort { $type_order{$a->{'Type'}} <=>
> $type_order{$b->{'Type'}}
> ||
> $b->{'Status(active/inactive)'} cmp
> $a->{'Status(active/inactive)'}
>
> } @records;
>
> which is exactly displaying the active records for a particular account
> type.
>
> Can further sorting on 'A/C No' so that all the active/inactive records
> for a particular account type should be displayed in sorted order.



Yes.

What happened when you tried it?

If you show us your broken code we will help you fix it.


--
Tad McClellan SGML consulting
Perl programming
Fort Worth, Texas
 
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
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
Array#inject to create a hash versus Hash[*array.collect{}.flatten] -- Speed, segfault Anthony Martinez Ruby 4 06-11-2007 08:16 AM
Sort by hash vaule, an array of hash references fahdsultan@gmail.com Perl Misc 11 10-10-2005 09:35 PM
Combining multiple hash references into one hash reference Arvin Portlock Perl Misc 6 09-02-2005 07:18 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57