Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何在散列中洗牌值?_Perl_Shuffle - Fatal编程技术网

Perl 如何在散列中洗牌值?

Perl 如何在散列中洗牌值?,perl,shuffle,Perl,Shuffle,我有一个字符串ID的散列。洗牌ID的最佳方式是什么 例如,my hash分配以下ID: this => 0 is => 1 a => 2 test => 3 现在我想随机洗牌。一个例子是: this => 1 is => 0 a => 3 test => 2 #!/usr/bin/perl use strict; use warnings; use List::Util qw/shuffle/; use Data::Dumper; my

我有一个字符串ID的散列。洗牌ID的最佳方式是什么

例如,my hash分配以下ID:

this => 0
is => 1
a => 2 
test => 3
现在我想随机洗牌。一个例子是:

this => 1
is => 0
a => 3
test => 2
#!/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;

您可以在中使用
shuffle
方法来帮助:

use List::Util qw(shuffle);

...

my @values = shuffle(values %hash);
map { $hash{$_} = shift(@values) } (keys %hash);

散列切片对我来说是最清晰的方式:

#!/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;
这有一个缺点,即当您取出它们的所有键和值时,庞大的哈希将占用大量内存。更有效的解决方案(从内存的角度来看)是:

this => 1
is => 0
a => 3
test => 2
#!/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;
此代码的优点是只需复制键(而不是键和值)

下面的代码不会随机化值(除非保证键的顺序是随机的),但它会混淆顺序。它的优点是可以在不占用太多额外内存的情况下就地工作:

#!/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;

您始终可以创建不同哈希的哈希,然后从中随机选择;)<代码>映射在void上下文中是一个令人憎恶的问题。这仅仅是一个样式问题,还是您对它有技术上的异议?(只是好奇)当
map
返回列表时(即使在无效上下文中),这是一个真正的问题。如今,这只是一个风格问题。有些人,像我一样,觉得依靠功能的副作用来工作是一件令人憎恶的事情。特别是当我们有一个同样短的结构,并且没有副作用时:
$hash{$\u}=shift@valuesforkeys%hash