5

有谁知道如何在 Perl 中以完全相同的方式随机打乱两个数组?例如,假设我有这两个数组:

洗牌前:数组1:1、2、3、4、5数组2:a、b、c、d、e

洗牌后:数组1:2、4、5、3、1数组2:b、d、e、c、a

因此,每个数组中的每个元素都绑定到其等效元素。

4

4 回答 4

22

尝试(类似)这个:

use List::Util qw(shuffle);
my @list1 = qw(a b c d e);
my @list2 = qw(f g h i j);
my @order = shuffle 0..$#list1;
print @list1[@order];
print @list2[@order];
于 2009-08-19T00:17:24.770 回答
9

第一:并行数组错误代码的潜在标志;您应该看看是否可以使用对象或哈希数组并为自己省去麻烦。

尽管如此:

use List::Util qw(shuffle);

sub shuffle_together {
  my (@arrays) = @_;

  my $length = @{ $arrays[0] };

  for my $array (@arrays) {
    die "Arrays weren't all the same length" if @$array != $length;
  }

  my @shuffle_order = shuffle (0 .. $length - 1);

  return map {
    [ @{$_}[@shuffle_order] ]
  } @arrays;
}

my ($numbers, $letters) = shuffle_together [1,2,3,4,5], ['a','b','c','d','e'];

基本上,用于shuffle以随机顺序生成索引列表,然后使用相同的索引列表对所有数组进行切片。

于 2009-08-19T00:22:07.287 回答
6

使用List::Util 打乱 shuffle索引列表并将结果映射到数组上。

use strict;
use warnings;

use List::Util qw(shuffle);

my @array1 = qw( a b c d e );
my @array2 = 1..5;

my @indexes = shuffle 0..$#array1;
my @shuffle1 = map $array1[$_], @indexes;
my @shuffle2 = map $array2[$_], @indexes;

更新 使用 Chris Jester-Young 的解决方案。 数组切片是我应该想到的更好的选择。

于 2009-08-19T00:16:51.603 回答
6

这是另一种方式:

use strict;
use warnings;

use List::AllUtils qw(pairwise shuffle);

my @list1 = qw(a b c d e);
my @list2 = qw(f g h i j);

my @shuffled_pairs = shuffle pairwise{[$a, $b]} @list1, @list2;

for my $pair ( @shuffled_pairs ) {
    print "$pair->[0]\t$pair->[1]\n";
}

输出:

C:\Temp> sfl
ej
bg
迪
af
ch

这样,您可以直接进行迭代,@shuffled_pairs而无需为索引保留额外的数组并避免 C 风格的循环。

于 2009-08-19T01:08:39.477 回答