: I would like to sort an array like this
: my @pets = {$cat, $dog,$camel,$camel,$camel,$dog}
: and then to have it printed out in the order of occurrences
: print "I will give you <3> camels, <2> dogs, <1> cat " for the blond one
Well, first of all, what you have there isn't really an array.
I'll assume that you meant was
my @pets = ($cat,$dog,$camel,$camel,$camel,$dog);
Next, I'll assume that you mean strings instead of variable names:
my @pets = ('cat','dog','camel','camel','camel','dog');
Otherwise, how could you tell that $dog was a dog?
If this is what you meant, then you can count them up with a hash:
my %count = ();
foreach my $pet ( @pets ) {
$count{$pet}++;
}
Then to get them back sorted by descending count:
my @petcounts = ();
foreach my $pet ( reverse sort {$a<=>$b} keys %count ) {
pushd @petcounts, sprintf "<%d> %s%s",
$count{$pet}, $pet, $pet == 1 ? "" : "s";
}
print "I will give you ", join(", ", @petcounts), " for the blond one.\n";
The second foreach loop creates each individual "<n> pet" statement and
puts them onto an array. Then it's easy to join then with ", ".
Plurals are taken care of by $pet == 1 ? "" : "s", which attaches an
"s" unless there's only one of them. ("mouse" will come out "mouses",
but I assume that if you're trading mouses for human beings, they'll be
the kind of deals where no one will care about your grammar. ;)
"reverse sort {$a<=>$b}" sorts the keys in reverse numerical order. You
could do the same thing with "sort {$b<=>$a}", leaving off the
"reverse".
-- tdk