Re: Getting the order of an array
by BrowserUk (Patriarch) on May 23, 2005 at 19:24 UTC
|
my @vector = qw( 27 32 46 5 102 76 );
my @order = sort{ $vector[ $a ] <=> $vector[ $b ] } 0 .. $#vector;
print @vector[ @order ];
5 27 32 46 76 102
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [d/l] |
|
|
Note that (this is more to OP) the OP said he wanted (or just expected) @order to contain 2,3,4,1,6,5 but in this solution (which i believe is correct) @order contains 3,0,1,2,5,4 ... Note especially the 1-based vs 0-based difference which is necessary for the array slice to work.
| [reply] |
|
|
{
local $[=1;
@order = sort{ $vector[ $a ] <=> $vector[ $b ] } 1 .. $#vector;
print @order;
}
4 1 2 3 6 5
though I wouldn't advise it. But accomating the reversal of the natural ordering without requiring sticking in unnecessary reverse calls all over the place was more of a problem.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [d/l] |
Re: Getting the order of an array
by dragonchild (Archbishop) on May 23, 2005 at 19:22 UTC
|
You mean you want to "Sort the indices of an array based on the values of that array?" That should help you out. And, yes, it is a one-liner.
- In general, if you think something isn't in Perl, try it out, because it usually is. :-)
- "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
| [reply] |
Re: Getting the order of an array
by NetWallah (Canon) on May 23, 2005 at 21:34 UTC
|
Another way of getting close to the OP's desired results:
UPDATE:Finally figured what the OP was trying for: - he needs both ORDER and RANK.
my @vector = qw( 27 32 46 5 102 76 );
my @order = map {$_+1}
sort{ $vector[ $a ] <=> $vector[ $b ] }
0 .. $#vector;
my ($r,@rank);
$rank[$_ - 1]= ++$r for @order;
unshift @vector,undef;
print qq(@rank\n@vector[@order]\n)
__Output__
2 3 4 1 6 5
5 27 32 46 76 102
The OP's definition of the sequence of @order was probably wrong.
The code looks funky because the OP seems to want a lower-bound of 1 instead of zero, for the @vector array.
"There are only two truly infinite things. The universe and stupidity, and I'm not too sure about the universe"- Albert Einstein
| [reply] [d/l] |
Re: Getting the order of an array
by 5mi11er (Deacon) on May 23, 2005 at 20:20 UTC
|
I'm also quite confused as the actual order of @vector according to the OP's @order would actually be (assuming 1 based indexes) 32, 46, 5, 27, 76, 102. This certainly isn't ordered numerically...
Update: From this post below, rank is a much better description than order. NetWallah++ for figuring this out.
-Scott | [reply] |
Re: Getting the order of an array
by tall_man (Parson) on May 23, 2005 at 21:09 UTC
|
To get the OP's desired output, one needs another loop such as the one below:
use strict;
my @vector = qw( 27 32 46 5 102 76 );
my @order = sort{ $vector[ $a ] <=> $vector[ $b ] } 0 .. $#vector;
my $i = 1;
my @order_it;
foreach (@order) {
$order_it[$_] = $i++;
}
print join(' ',@order_it),"\n";
print "@vector[ @order ]\n";
Update: Updated to show the correct way to get the second part of the OP's answer. In answer to BrowserUk's comment, I took the original question to mean that both outputs are required but that the OP didn't realize they could not both be supported by a single array. | [reply] [d/l] |
|
|
use strict;
my @vector = qw( 27 32 46 5 102 76 );
my @order = sort{ $vector[ $a ] <=> $vector[ $b ] } 0 .. $#vector;
my $i = 1;
my @order_it;
foreach (@order) {
$order_it[$_] = $i++;
}
print join(' ',@order_it),"\n";
print "@vector[ @order_it ]\n";
__END__
P:\test>junk
2 3 4 1 6 5
Use of uninitialized value in join or string at P:\test\junk.pl line 1
+1.
46 5 102 32 76
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [d/l] |