Самый понятный способ для меня - ломтик хеша:
#!/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;
Это имеет недостаток в том, что огромные хэши занимают много памяти, когда вы извлекаете все их ключи и значения. Более эффективное (с точки зрения памяти) решение было бы:
#!/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;
Преимущество этого кода состоит в том, что ему приходится только дублировать ключи (а не ключи и значения).
Следующий код не рандомизирует значения (кроме Perl 5.8.1 , где порядок ключей гарантированно является случайным), но он смешивает порядок. Преимущество работы на месте без чрезмерного использования памяти:
#!/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;