Una rebanada de hash sería la forma más clara para mí:
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw/shuffle/;
use Data::Dumper;
my %h = (
this => 0,
is => 1,
a => 2,
test => 3,
);
@h{keys %h} = shuffle values %h;
print Dumper \%h;
Esto tiene el inconveniente de que los valores hash enormes ocuparían mucha memoria a medida que sacaras todas sus claves y valores. Un (a partir de un punto de vista de la memoria) la solución más eficiente sería:
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw/shuffle/;
use Data::Dumper;
my %h = (
this => 0,
is => 1,
a => 2,
test => 3,
);
{ #bareblock to cause @keys to be garbage collected
my @keys = shuffle keys %h;
while (my $k1 = each %h) {
my $k2 = shift @keys;
@h{$k1, $k2} = @h{$k2, $k1};
}
}
print Dumper \%h;
Este código tiene la ventaja de tener sólo para duplicar las teclas (en lugar de las claves y valores).
El siguiente código no aleatoria de los valores (excepto en Perl 5.8.1 donde el orden de las claves se garantiza que sea al azar), pero no mezclar el orden. Se tiene el beneficio de trabajar en su lugar sin demasiado uso de memoria adicional:
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw/shuffle/;
use Data::Dumper;
my %h = (
this => 0,
is => 1,
a => 2,
test => 3,
);
my $k1 = each %h;
while (defined(my $k2 = each %h)) {
@h{$k1, $k2} = @h{$k2, $k1};
last unless defined($k1 = each %h);
}
print Dumper \%h;
Siempre se puede crear un hash de hashes diferentes al azar y luego seleccionar uno de esos;) – hemlocker