كيف يمكنني خلط صفيفتين بنفس الطريقة بالضبط في بيرل؟
سؤال
هل يعرف أحد كيفية خلط صفيفين بشكل عشوائي بنفس الطريقة بالضبط في بيرل؟ على سبيل المثال، أقول لدي هاتين الصفيفين:
قبل خلط: الصفيف 1: 1، 2، 3، 4، 5 الصفيف 2: أ، ب، ج، د، ه
بعد خلط: الصفيف 1: 2، 4، 5، 3، 1 صفيف 2: B، D، E، C،
لذلك كل عنصر في كل مجموعة مرتبط بعنصرها المعادل.
المحلول
حاول (شيء مثل) هذا:
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];
نصائح أخرى
أولا: صفيفات متوازية نكون علامة محتملة على رمز سيئة؛ يجب أن ترى ما إذا كان يمكنك استخدام مجموعة من الكائنات أو التجزئة وحفظ نفسك في هذه المشكلة.
ومع ذلك:
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
لإنتاج قائمة من المؤشرات بأمر عشوائي، ثم شريحة جميع المصفوفات بنفس قائمة المؤشرات.
يستخدم القائمة :: eltil 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;
تحديثاستخدم محلول كريس جست - يونغ. شرائح الصفيف هي خيار أفضل يجب أن أفكر فيه.
هنا طريقة أخرى:
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 DI AF CH
بهذه الطريقة، يمكنك التكرار مباشرة @shuffled_pairs
دون الحاجة إلى الحفاظ على مجموعة إضافية للفهارس وتجنب حلقات نمط C.