代码之家  ›  专栏  ›  技术社区  ›  Abdel

如何在Perl中以完全相同的方式洗牌两个数组?

  •  5
  • Abdel  · 技术社区  · 15 年前

    有人知道如何用Perl中完全相同的方式随机洗牌两个数组吗? 例如,假设我有两个数组:

    洗牌前: 数组2:a、b、c、d、e

    数组1:2,4,5,3,1 数组2:b,d,e,c,a

    所以每个数组中的每个元素都绑定到它的等价元素。

    4 回复  |  直到 15 年前
        1
  •  22
  •   C. K. Young    15 年前

    试着这样做:

    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
  •   hobbs    15 年前

    第一:并行阵列

    尽管如此:

    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 以随机顺序生成索引列表,然后使用相同的索引列表对所有数组进行切片。

        3
  •  6
  •   daotoad    15 年前

    使用 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的解决方案。 Array slices

        4
  •  6
  •   Sinan Ünür    15 年前

    还有一种方法:

    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
    e       j
    b       g
    d       i
    a       f
    c       h
    

    这样,您就可以直接在 @shuffled_pairs 无需为索引保留额外的数组,也无需避免C样式的循环。