Does anyone know how to shuffle two arrays randomly in exactly the same way in Perl? For example, say I have these two arrays:
有没有人知道如何在Perl中以完全相同的方式随机混乱两个数组?例如,假设我有这两个数组:
Before shuffling: array 1: 1, 2, 3, 4, 5 array 2: a, b, c, d, e
在改组之前:阵列1:1,2,3,4,5阵列2:a,b,c,d,e
After shuffling: array 1: 2, 4, 5, 3, 1 array 2: b, d, e, c, a
改组后:阵列1:2,4,5,3,1阵列2:b,d,e,c,a
So every element in each array is bound to its equivalent element.
因此每个数组中的每个元素都绑定到它的等效元素。
4 个解决方案
#1
22
Try (something like) this:
尝试(像这样):
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];
#2
9
First: parallel arrays are a potential sign of bad code; you should see if you can use an array of objects or hashes and save yourself that trouble.
第一:并行数组是代码错误的潜在迹象;你应该看看你是否可以使用一组对象或哈希值,并为自己省去麻烦。
Nonetheless:
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'];
Basically, use shuffle
to produce a list of indices in random order, and then slice all of the arrays with the same list of indices.
基本上,使用shuffle以随机顺序生成索引列表,然后使用相同的索引列表对所有数组进行切片。
#3
6
Use List::Util shuffle
to shuffle a list of indexes and map the results onto the arrays.
使用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;
Update Use Chris Jester-Young's solution. Array slices are a better choice that I should have thought of.
更新使用Chris Jester-Young的解决方案。数组切片是我应该想到的更好的选择。
#4
6
Here is another way:
这是另一种方式:
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";
}
Output:
C:\Temp> sfl e j b g d i a f c h
This way, you can iterate directly over @shuffled_pairs
without needing to keep an extra array for the indexes and avoid C-style loops.
这样,您可以直接在@shuffled_pairs上进行迭代,而无需为索引保留额外的数组,并避免使用C风格的循环。
#1
22
Try (something like) this:
尝试(像这样):
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];
#2
9
First: parallel arrays are a potential sign of bad code; you should see if you can use an array of objects or hashes and save yourself that trouble.
第一:并行数组是代码错误的潜在迹象;你应该看看你是否可以使用一组对象或哈希值,并为自己省去麻烦。
Nonetheless:
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'];
Basically, use shuffle
to produce a list of indices in random order, and then slice all of the arrays with the same list of indices.
基本上,使用shuffle以随机顺序生成索引列表,然后使用相同的索引列表对所有数组进行切片。
#3
6
Use List::Util shuffle
to shuffle a list of indexes and map the results onto the arrays.
使用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;
Update Use Chris Jester-Young's solution. Array slices are a better choice that I should have thought of.
更新使用Chris Jester-Young的解决方案。数组切片是我应该想到的更好的选择。
#4
6
Here is another way:
这是另一种方式:
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";
}
Output:
C:\Temp> sfl e j b g d i a f c h
This way, you can iterate directly over @shuffled_pairs
without needing to keep an extra array for the indexes and avoid C-style loops.
这样,您可以直接在@shuffled_pairs上进行迭代,而无需为索引保留额外的数组,并避免使用C风格的循环。