Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl: shuffle value-sorted hash?

Tags:

sorting

hash

perl

At first sorry for my english - i hope you will understand me.

There is a hash:

$hash{a} = 1;
$hash{b} = 3;
$hash{c} = 3;
$hash{d} = 2;
$hash{e} = 1;
$hash{f} = 1;

I want to sort it by values (not keys) so I have:

for my $key ( sort { $hash{ $a } <=> $hash{ $b } } keys %hash  ) { ... }

And at first I get all the keys with value 1, then with value 2, etc... Great.

But if hash is not changing, the order of keys (in this sort-by-value) is always the same.

Question: How can I shuffle sort-results, so every time I run 'for' loop, I get different order of keys with value 1, value 2, etc. ?

like image 375
gib Avatar asked Jan 18 '26 09:01

gib


2 Answers

Not quite sure I well understand your needs, but is this ok:

use List::Util qw(shuffle);

my %hash;
$hash{a} = 1;
$hash{b} = 3;
$hash{c} = 3;
$hash{d} = 2;
$hash{e} = 1;
$hash{f} = 1;

for my $key (sort { $hash{ $a } <=> $hash{ $b } } shuffle( keys %hash  )) {
    say "hash{$key} = $hash{$key}"
}
like image 69
Toto Avatar answered Jan 21 '26 00:01

Toto


You can simply add another level of sorting, which will be used when the regular sorting method cannot distinguish between two values. E.g.:

sort { METHOD_1 || METHOD_2 || ... METHOD_N } LIST

For example:

sub regular_sort {
    my $hash = shift;
    for (sort { $hash->{$a} <=> $hash->{$b} } keys %$hash) {
        print "$_ ";
    };
}
sub random_sort {
    my $hash = shift;
    my %rand = map { $_ => rand } keys %hash;
    for (sort { $hash->{$a} <=> $hash->{$b} ||
        $rand{$a} <=> $rand{$b} } keys %$hash ) {
        print "$_ ";
    };
}
like image 44
TLP Avatar answered Jan 21 '26 01:01

TLP