如何在Perl中将数组值拆分为新的单独数组?

ver*_*cat 3 regex arrays perl split push

我是学习Perl的初学者。我在这里尝试做的是拆分数组@value并将其插入新数组。我的问题是,我不完全知道如何使我的代码循环运行并获得所需的结果。

是否可以使用此方法获得所需的结果,或者是否有其他替代方法/方法来获得相同的结果?

我的代码如下:

my @separated = ();
my @separated1 = ();
my @separated2 = ();
my @separated3 = ();
my $counter = 0;
my @values = "aaa 111 AAA bbb 222 BBB ccc 333 CCC ddd 444 DDD";

foreach (@values) {
my @separated = split(' ', $_);
push @separated1, $separated[0];
push @separated2, $separated[1];
push @separated3, $separated[2];
}
$counter++

print "separated1 = @separated1\n";
print "separated2 = @separated2\n";
print "separated3 = @separated3\n";
Run Code Online (Sandbox Code Playgroud)

我得到的结果;

分隔的1 = aaa

分隔2 = 111

3 = AAA

所需结果;

分隔的1 = aaa bbb ccc ddd

分隔2 = 111222333444

3 = AAA BB CCC DD

ike*_*ami 5

my ( @foos, @bars, @quxs );
my @values = split(' ', $input);
while (@values) {
   push @foos, shift(@values);
   push @bars, shift(@values);
   push @quxs, shift(@values);
}
Run Code Online (Sandbox Code Playgroud)

上面也可以写成如下形式:

my ( @foos, @bars, @quxs );
for ( my @values = split(' ', $input); @values; ) {
   push @foos, shift(@values);
   push @bars, shift(@values);
   push @quxs, shift(@values);
}
Run Code Online (Sandbox Code Playgroud)

您确定要并行数组吗?尽管它们可以节省内存,但通常很难与它们一起使用,并且更容易出错。在以对象为主的环境中,它们几乎是看不到的。

您可以使用AoA:

my @moos;
my @values = split(' ', $input);
while (@values) {
   push @moos, [ splice(@values, 0, 3) ];
}
Run Code Online (Sandbox Code Playgroud)

您可以使用AoH:

my @moos;
my @values = split(' ', $input);
while (@values) {
   my %moo; @moo{qw( foo bar qux )} = splice(@values, 0, 3);
   push @moos, \%moo;
}
Run Code Online (Sandbox Code Playgroud)


zdi*_*dim 5

一种罕见的场合,其中C风格的for循环适用于迭代每个第3个元素

my $string = 'aaa 111 AAA bbb 222 BBB ccc 333 CCC ddd 444 DDD';

my (@sep1, @sep2, @sep3);

my @values = split ' ', $string;

for (my $i=0; $i <= $#values; $i += 3) {
    push @sep1, $values[$i];
    push @sep2, $values[$i+1];
    push @sep3, $values[$i+2];
}
Run Code Online (Sandbox Code Playgroud)

假设数组确实具有所有三元组,或者更好地检查每个元素。

但是通常使用单个结构比使用一组并行数组要好得多。例如,使用具有作为数组引用的元素的数组

use Data::Dump qw(dd);

my @sep;

for (my $i=0; $i <= $#values; $i += 3) { 
    for my $j (0..2) { 
        push @{$sep[$j]}, $values[$i+$j]; 
    }
}

dd \@sep;
Run Code Online (Sandbox Code Playgroud)

使用更清洁的方法可以避免重复迭代

for my $i (0..$#values) { 
    push @{$sep[$i%3]}, $values[$i] 
}
Run Code Online (Sandbox Code Playgroud)

它替换了两个循环。

此打印

[
  [“ aaa”,“ bbb”,“ ccc”,“ ddd”],
  [111、222、333、444],
  [“ AAA”,“ BBB”,“ CCC”,“ DDD”],
]

我使用Data :: Dump查看复杂数据。核心中的替代方法是Data :: Dumper


然后,有许多带有各种实用程序例程的模块可用于处理列表。

例如,使用部分一览:: MoreUtils到分隔@values阵列

my @sep = map { [ @values[@$_] ] } part { $_%3 } 0..$#values;
Run Code Online (Sandbox Code Playgroud)

@sep与上面的arrayrefs 产生相同的结果。

part收益arrayrefs的名单,因为它包含的每个分区索引的索引列表@values。然后在map中将每个arrayref评估到其索引列表(@$_)中,该列表用于获取@values; 的对应切片;该列表用于使用制作arrayref []。因此map返回arrayrefs的列表,并根据需要对值进行分区。

有关使用参考的信息,请参见perlreftut教程和参考perlref