Perl 中是否有任何函数可以移动数组元素而不删除它们?

Is there any function in Perl that shifts the array element without removing them?

我有一个数组,比如 @array1 = qw(abc def ghi jkl)

现在,我想以元素逐一移动的方式使用此数组,但这种移动实际上是发生的,而不是在数组中。

就像,“shift”将移动元素并将它们从数组中删除。但是,我不想删除这些元素。

短代码片段:

while (my $rName = shift @array1) { 
    my $bName = shift @array1 ; 
    ## Do something now with the value 
}
##And now, I want that I can use @array1 again with the original elements residing

如何实现?

使用 C-style for 循环并递增 2。 $#foo 是最后一个元素的索引。

my @foo = 0 .. 5;
for (my $i = 0; $i <= $#foo; $i += 2){
    my $r_name = $foo[$i];
    my $b_name = $foo[$i+1];
}

如果您想要 fancier-looking 代码,您可以在 CPAN 上使用 natatime from List::MoreUtils,它为您提供了一个可以在 while 循环中使用的迭代器。

use List::MoreUtils 'natatime';

my @foo = 0 .. 5;
my $it = natatime 2, @foo;
while ( my ($r_name, $b_name) = $it->() ) {
    print "$r_name $b_name\n";
}

您还可以使用核心 List::Util 模块中的 pairs

A convenient shortcut to operating on even-sized lists of pairs, this function returns a list of ARRAY references, each containing two items from the given list.

#!/usr/bin/env perl                                                                                                                                                                                                                               
use strict;
use warnings;
use feature qw/say/;
use List::Util qw/pairs/;

my @array1 = qw/a 1 b 2 c 3/;
for my $pair (pairs @array1) {
    my ($rName, $bName) = @$pair;
    say "$rName => $bName";
}
say "@array1";

Perl 5.36 中,您将能够做到这一点:

for my ($rName, $bName) (@array1) { ... }
# Require Perl 5.36
for my ( $rName, $bName ) ( @array1 ) {
   ...
}
my @array2 = @array1;
while ( @array2 ) {
   my $rName = shift @array2;
   my $bName = shift @array2; 
   ...
}
for my $i ( 0 .. $#array1/2 ) {
   my $rName = $array1[ $i * 2 + 0 ];
   my $bName = $array1[ $i * 2 + 1 ];
   ...
}
for ( my $i = 0; $i < @array1; ) {
   my $rName = $array1[ $i++ ];
   my $bName = $array1[ $i++ ];
   ...
}
use List::Util qw( pairs );

for ( pairs @array1 ) {
   my ( $rName, $bName ) = @$_;
   ...
}

我试图从最快到最慢来组织它们,但实际上我并没有对任何东西进行基准测试。

前面提到了其中三个解决方案,但没有人提到我认为不需要 5.36(尚未发布)的最快解决方案。