我有这些数组集合,每个数组都有两个元素。
@a = ("a", "b");
@i = (1, 2);
@s = ( "\\!", "\?");
如何使结果返回
a1!, b2?
我需要它们是像这样的数组的新集合
@new =(a1!,b2?)
我编写了用于输出答案的代码
$i = length(@a);
for (0..$1) {
@array = push(@array, @a[$i], @s[$i];
}
print @array;
但是,它仅返回
syntax error at pra.pl line 10, near "];"
谢谢。
答案 0 :(得分:4)
您有一个基本的想法,那就是使用数组的索引同时进行迭代。但是该代码有许多基本错误,并且也不能像示例所示那样进行。我建议先全面了解现代的Perl教程。
示例表明您要在每个索引处串联(请参见.
operator)元素
use warnings;
use strict;
use feature 'say';
my @a1 = ('a', 'b');
my @a2 = (1, 2);
my @a3 = ('!', '?');
my @res;
foreach my $i (0..$#a1) {
push @res, $a1[$i] . $a2[$i] . $a3[$i];
}
say for @res;
其中$#a1
是数组@a1
的最后一个元素的索引。假设所有数组的大小都相同,并且所有元素都已定义。
这项精确的工作可以在一条语句中使用map完成
my @res = map { $a1[$_] . $a2[$_] . $a3[$_] } 0..$#a1;
具有相同的严肃假设。即使您知道他们持有,您是否肯定在每次运行任何数据时都 ?有关可靠的方法,请参见answer by mwp。
each_array中还有List::MoreUtils,为所有数组提供“同时迭代器”
my $ea = each_array(@a1, @a2, @a3);
my @res;
while ( my ($e1, $e2, $e3) = $ea->() ) {
push @res, $e1 . $e2 . $e3
}
对于更复杂的处理真的很有用。
快速浏览基础知识
程序的开头始终带有use warnings;
和use strict;
。他们将捕获许多错误,否则将花费很多时间和神经。
不要使用单字母变量名称。我们很快就忘记了它们的含义,并且代码变得难以遵循,而且它们也很容易造成愚蠢的错误。
数组的大小不是由length
给出。通常使用context获得它-将数组分配给标量时,将返回其元素数。对于索引上的迭代,有$#ary
,即@ary
的最后一个元素的索引。然后,索引列表为0 .. $#ary
,使用range (..
) operator
标识符(变量名)开头的符号($
,@
,%
)表示type of the variable(标量,数组,哈希)。数组元素是标量,因此需要$
-$ary[0]
push不会返回数组元素,而是将其后面列表中的标量添加到其第一个参数中的数组。
print @array;
打印数组元素,它们之间没有任何内容。引用时会添加空格,print "@array\n";
。不过请注意方便的feature say
,它将添加新行。
答案 1 :(得分:4)
use 5.008;
use List::AllUtils qw(zip_by);
⋮
my @new = zip_by { join '', @_ } \@a, \@i, \@s;
zip_by
是CPAN上List::AllUtils
模块的子例程。因此它不是内置的。
use v6;
⋮
my @new = map { .join }, zip @a, @i, @s;
在Perl 6中,zip
已经成为标准库的一部分。这种额外的解决方案在这里很有用,这是一个展示优势的机会:可以完成相同的工作,但是语法比较少,并且可以立即使用。
v6
并非绝对必要,在这里我只是将其用作对比来表示版本。但是在文件的开头,它还具有不错的属性,如果您不小心在Perl 5中运行了Perl 6代码,您将得到一个不错的错误消息,而不是一个隐秘的语法错误。尝试一下!来自use VERSION
documentation:
如果VERSION大于当前Perl的版本,则会引发异常。
答案 2 :(得分:2)
use strict;
和use warnings;
(并使用my
声明变量)。?
和!
,并且可以使用qw//
类似引号的运算符来轻松构建术语列表。length(@a)
来确定最后一个索引,但是Perl数组索引是从零开始的,因此最后一个索引实际上是length(@a) - 1
。 (但这仍然不正确。请参阅下一点...)length
函数用于字符串。$i
,但随后在下一行引用了变量$1
。这是两个不同的变量。$_
)。$a[$i]
,而不是@a[$i]
。因为只需要一个标量值,所以表达式必须以标量符号$
开头。 (相反,如果您希望从表达式中获取值列表,则可以使用数组@
来表示该表达式。)push
修改第一个参数给出的数组,因此无需将结果分配回表达式中的数组。 push
表达式中缺少右括号。@new
和@array
,并且仅添加了@a
和@s
中的元素(即您忘记了@i
)。这是您的实现的有效版本:
use strict;
use warnings;
use List::Util qw{max};
my @a = ("a", "b");
my @i = ("1", "2");
my @s = ("!", "?");
my @array;
my $length = max scalar @a, scalar @i, scalar @s;
foreach my $i (0 .. $length - 1) {
push @array, ($a[$i] // '') . ($i[$i] // '') . ($s[$i] // '');
}
print @array;
(//
的意思是“定义或”。
这是我的写法:
use strict;
use warnings;
use List::Util qw{max};
my @a = qw/a b/;
my @i = qw/1 2/;
my @s = qw/! ?/;
my @array = map {
join '', grep defined, $a[$_], $i[$_], $s[$_]
} 0 .. max $#a, $#i, $#s;
print "@array\n";
($#a
的意思是“给我数组@a
的最后一个元素的索引。”)
答案 3 :(得分:-1)
use warnings;
use strict;
use Data::Dumper;
my $result = [];
my @a = ("a", "b");
my @i = (1, 2);
my @s = ( "\!", "\?");
my $index = 0;
for my $a ( @a ) {
push( @$result, ($a[$index], $i[$index], $s[$index]) );
$index = $index + 1;
}
print Dumper(@$result);