Descending sort

C

Colossus

Hi,

I have a flat database file this way:

A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110

The fields are tab separated. I want it this way:
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39

I grabbed this piece of code but it doesn't work:

foreach my $MyData (sort { $a->[1] <=> $b->[1] } map{[$_, /^(\d+)/]} @temp)
{
printf "%-15s%5d: %-s\n", ' ', $MyData->[1], $MyData->[0];
}

I understand the problem is regular expression in map. I also
tried to use $b->4 <=> $a->4 because the field I have to order by
is at fourth position but nothing to do ! Could anyone help me please ?
 
A

Anno Siegel

Colossus said:
Hi,

I have a flat database file this way:

A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110

The fields are tab separated. I want it this way:
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39

What is this? A puzzle to amuse the regulars? Believe me, we can do
without those.

No column in your proposed output data is sorted, neither ascending
nor descending. An example fine, but it is is never enough to explain
your intentions. You must also explain in words what you want to do.
I grabbed this piece of code but it doesn't work:

foreach my $MyData (sort { $a->[1] <=> $b->[1] } map{[$_, /^(\d+)/]} @temp)
{
printf "%-15s%5d: %-s\n", ' ', $MyData->[1], $MyData->[0];

Your sprintf format provides for three data elements, but you're only
printing two. It can never print anything like your proposed output.

That's a Schwartz transform for sorting strings that contain a number
into descending order. What on earth made you think it is applicable
to your problem?
I understand the problem is regular expression in map. I also

You'd need a pretty formidable regex to extract fields that sort
according to your example. Why do you believe you need a regex
to extract sort fields? Sort field extraction is trivially done
through split(), it is not your problem.
tried to use $b->4 <=> $a->4 because the field I have to order by

If you did try that, Perl would have told you it is a syntax error.
Please take some care in reporting what you tried. You may have tried
is at fourth position but nothing to do ! Could anyone help me please ?

Your example output is consistent with a combined sort strategy: Sort
(alphabetically, descending) by the first field. If the first fields
are equal, sort (numerically, ascending) by the fifth field.

Here is how it can be done:

#!/usr/bin/perl
use strict; use warnings; $| = 1; # @^~`

# build an array of arrays, each containing the fields of one line
my @raw = map [ split ], <DATA>;

# sort them
my @sorted = sort { $a->[ 0] cmp $b->[ 0] or $b->[ 4] <=> $a->[ 4] } @raw;

# show the output
use Text::Table;
my $tb = Text::Table->new( ( '') x 5);
$tb->load( @sorted);
print $tb;

__DATA__
A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110

Anno
 
C

Colossus

Anno said:
Your example output is consistent with a combined sort strategy: Sort
(alphabetically, descending) by the first field. If the first fields
are equal, sort (numerically, ascending) by the fifth field.

I took that code from the newsgroup perl.beginners in a message of 2002:

http://groups.google.com/groups?hl=...AB033B24A1%40pmail02.vikingfreight.com&rnum=6

I tried to adapt to my problem but without success. Could you please explain
me why I have to sort alphabetically the first fields and then sort by the
fifth one ? Can I sort directly by the fifth one ?

Thank you so much for your answer.
 
C

Colossus

@array = ("A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39",
"A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110",
"A02759.PE1 XLA298150.APP HBG000051 0.12417 592",
"A08691.RAP1A AF032713.PE1 HBG009351 0.63293 333",
"A08802.PE1 AF349034.PE1 HBG000071 0.82133 386",
"A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39",
"A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386",
"A14829.PE1 AF042219.PE1 HBG004257 2.03983 110");

my @sorted = sort { $a->[ 0] cmp $b->[ 0] or $b->[ 4] <=> $a->[ 4] }
@array;

foreach $indice(0..$#sorted)
{
print $sorted[$indice],"\n";
}

Output:

A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A02759.PE1 XLA298150.APP HBG000051 0.12417 592
A08691.RAP1A AF032713.PE1 HBG009351 0.63293 333
A08802.PE1 AF349034.PE1 HBG000071 0.82133 386
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110

That is exactly the same starting array.
 
G

Gunnar Hjalmarsson

Colossus said:
That is exactly the same starting array.

Have you possibly considered to "grab" some Perl documentation, rather
than grabbing various pieces of code that you don't understand?

A suitable starter might be

perldoc -f sort
 
A

Anno Siegel

Colossus said:
I took that code from the newsgroup perl.beginners in a message of 2002:

http://groups.google.com/groups?hl=...AB033B24A1%40pmail02.vikingfreight.com&rnum=6

I tried to adapt to my problem but without success. Could you please explain
me why I have to sort alphabetically the first fields and then sort by the
fifth one ?

What's to explain? *You* gave the example, and that's a way to reproduce
your example.
Can I sort directly by the fifth one ?

You can, but that won't give you the sequence of your example.

Anno
 
A

Anno Siegel

Colossus said:
What you call suitable is a very difficult
explanation on how to sort an array of more fields.

So you want to use the sort function, but the documentation is too
difficult? "Suitable" isn't the same as "simple".

Anno
 
C

Colossus

Anno said:
So you want to use the sort function, but the documentation is too
difficult? "Suitable" isn't the same as "simple".

Still your code doesn't work, I think it is much
better for you not to answer at all. Did you read
the documentation about sort ? You write perl code
that works only in your brain.
 
A

Anno Siegel

Colossus said:
Still your code doesn't work, I think it is much
better for you not to answer at all. Did you read
the documentation about sort ? You write perl code
that works only in your brain.

Sure it works. You botched it when you gave my sort routine an array
of strings instead an array of arrays of fields. If you had switched
on warnings or strictures, you'd already know that something was
wrong. You should always switch them on in troublesome code.

I get the impression you have very little experience in programming.
There's nothing wrong with that, but you have probably bitten off
a little more than you can chew at the moment. Get acquainted with
the basics first. What *is* wrong is to over-estimate your own
abilities.

Anno
 
T

Tore Aursand

No column in your proposed output data is sorted, [...]

Really? It seems to me that the data is sorted based on the values of
columns 3 and 5.

But! It's quite a guess from me, though; The OP _should_ have given us a
better understanding of what (s)he really want to do.
 
T

Tore Aursand

I have a flat database file this way:

A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110

The fields are tab separated. I want it this way:
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39

Well. You don't actually tell us the criteria for your sorting, but it
seems to me that you'd like to sort the numeric value of column 5, then by
column 3, in a descending order.

For that, use Sort::Fields from CPAN.
 
M

Michele Dondi

@array = ("A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39",
"A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110",
[snip]

First of all, may you be so kind in the future and quote properly any
post you're answering to? And in case you (really need/want to) change
the subject line, please indicate so (by including e.g. "[was:
something else]").

There's quite a lot of traffic here, and a lot of helpful and
knowlegdeable people too (not me!), but because of the former, the
latter ones need help to help you. This includes giving some
references about what's going one.

For example here I can understand what is *wrong*, but I hardly have a
clue on how to make it *right* wrt what *you want* (but please see
below!).

One nice feature of this NG is that posting guidelines are posted here
regularly to the effect of "helping others to help you". Personally I
don't think it's *necessary* to read them, but surely it can't do
harm! And if someone (one of the helpful and knowlegdeable people!)
took care of writing them, it may well be worth!
my @sorted = sort { $a->[ 0] cmp $b->[ 0] or $b->[ 4] <=> $a->[ 4] }
@array;

So your sort routine is designed to sort an AoA by comparing some
fields of the "inner arrays" (yes: I know all this is very imprecise,
but hopefully it will be easier to understand for the OP!).

You're feeding the sort routine *an array of strings* instead! Have
you considered reading

perldoc -f sort

and

perldoc -q 'sort an array by'

especially the bit about "Schwartzian Transform"?!? This seems exactly
what you need.
foreach $indice(0..$#sorted)
{
print $sorted[$indice],"\n";
}

This portion of code seems rather awkward. Why not use

#!/usr/bin/perl -l
# ^^ if this doesn't "conflict" with anything else!!
...
print for @sorted;

or

{
local $\="\n";
print for @sorted;
}

or

{
local ($\,$,)="\n";
print @sorted;
}

instead?
Output: [snip]
That is exactly the same starting array.

The reason is explained above. As I said, I don't really know what you
would like to do. But taking into account what I read above, I can
*guess*, so here's my try; please do *not* complain if that doesn't do
what you expected:

#!/usr/bin/perl -l
use strict;
use warnings;

chomp (my @array = <DATA>);

print for map $_->[0],
sort { $a->[1] cmp $b->[1] or $b->[2] <=> $a->[2] } map
[$_, (split)[0,4]], @array;
__END__
A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A02759.PE1 XLA298150.APP HBG000051 0.12417 592
A08691.RAP1A AF032713.PE1 HBG009351 0.63293 333
A08802.PE1 AF349034.PE1 HBG000071 0.82133 386
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110

This gives me:

A00469.PE1 SGGH2.PE1 HBG011318 1.26943 110
A00469.PE1 SSGGH.PE1 HBG011318 1.26943 39
A02759.PE1 XLA298150.APP HBG000051 0.12417 592
A08691.RAP1A AF032713.PE1 HBG009351 0.63293 333
A08802.PE1 AF349034.PE1 HBG000071 0.82133 386
A14829.PE1 DRAPLIPAI.PE1 HBG004257 1.96625 386
A14829.PE1 AF042219.PE1 HBG004257 2.03983 110
A14829.PE1 SSAPOLAI.PE1 HBG004257 1.88791 39

Is this what you wanted?!?


HTH,
Michele
 
A

Anno Siegel

Tore Aursand said:
No column in your proposed output data is sorted, [...]

Really? It seems to me that the data is sorted based on the values of
columns 3 and 5.

So no column is sorted, qed :)

Since columns 1 and 3 agree in all visible cases, the result is also
sorted wrt columns 1 and 5, which is what I happened to notice first.
Such are the possible (and actual) misunderstandings caused by a
lacking description.
But! It's quite a guess from me, though; The OP _should_ have given us a
better understanding of what (s)he really want to do.

Indeed.

Anno
 
C

Colossus

Tore said:
Well. You don't actually tell us the criteria for your sorting, but it
seems to me that you'd like to sort the numeric value of column 5, then by
column 3, in a descending order.

For that, use Sort::Fields from CPAN.
I think that the obvious things are very difficult to understand. From my
example is very clear that I want to sort from the last field in descending
sort.
 
C

Colossus

Anno said:
I get the impression you have very little experience in programming.
There's nothing wrong with that, but you have probably bitten off
a little more than you can chew at the moment.  Get acquainted with
the basics first.  What is wrong is to over-estimate your own
abilities.

I'm not an expert in programming but I'm humble and eagier to
learn more and more by asking the help of others and that's why
I posted the question. Unfortunately on this newsgroups as in the worls
there are very proud person like you and the others who replied me (apart
Michele Dondi) who feel authorized to mistreat beginners like me only
because they are "expert" in programming, that is all. I just asked
help because I was not able to accomplish the problem neither reading
the perldoc -f sort neither reading "Perl documentation". It is not a fault
to grab a piece of code written by others, but you and the others with your
proud answers mean just that. Just a counsel to you and the others who
replied me: don' start useless flames, but please be useful for others: if
you know the solution to their problem answer them otherwise don't do it.
 
C

Colossus

Michele said:
First of all, may you be so kind in the future and quote properly any
post you're answering to? And in case you (really need/want to) change
the subject line, please indicate so (by including e.g. "[was:
something else]").

Ok, I commited a mistake. Sorry for that.
There's quite a lot of traffic here, and a lot of helpful and
knowlegdeable people too (not me!), but because of the former, the
latter ones need help to help you. This includes giving some
references about what's going one.

I was clear Michele, I've even provided the example output after
the sort.
One nice feature of this NG is that posting guidelines are posted here
regularly to the effect of "helping others to help you". Personally I
don't think it's *necessary* to read them, but surely it can't do
harm! And if someone (one of the helpful and knowlegdeable people!)
took care of writing them, it may well be worth!

Again ? Ok I committed a mistake by changing the subject line and
forgetting to insert: was: bla bla bla but it's not the case to exagerate !
So your sort routine is designed to sort an AoA by comparing some
fields of the "inner arrays" (yes: I know all this is very imprecise,
but hopefully it will be easier to understand for the OP!).

It's not mine, but as I wrote it's a piece of code grabbed from another
newsgroup, it seems you have read only the subject line.
You're feeding the sort routine *an array of strings* instead! Have
you considered reading

That 's what I want, I didn't know that the grapped piece of code was
designed to sort an array of array.
perldoc -f sort and perldoc -q 'sort an array by'
especially the bit about "Schwartzian Transform"?!? This seems exactly
what you need.

I already did but that code/example goes far beyond my knowledge that is
why I asked help here, no need to behave harshly regarding the beginners.
This portion of code seems rather awkward. Why not use

Because this is easy to understand Michele, that's why I use it
and I will continue to use it.
The reason is explained above. As I said, I don't really know what you
would like to do. But taking into account what I read above, I can
*guess*, so here's my try; please do *not* complain if that doesn't do
what you expected:

I will not complain, I wouldn't have complained to Aron if he had been
more polite toward me.
Is this what you wanted?!?

Yeah, so my example was clear wasn't it ?
A flame arised for an easy task.
Bah, people are really stupid !

Thank you for answering,
 
C

Colossus

Robert said:
Then maybe programming isn't for you?

Ah ah ah ah ah ! That is very funny ! Programming must
be difficult otherwise it is not programming ? Ah ah ah ah ah !
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top