当列表不止一个时,我需要打印逗号“,”,如果不止一个,则我不想打印逗号。我知道我可以使用Join来执行此操作,但是如果要添加另一个@FAMILIES,则无法使用逗号循环@NAMES。
#!/usr/bin/perl
use strict;
use warnings;
my @NAMES = qw(ALLIES BOBBY CAKRA);
my @FAMILIES = qw(A B C);
foreach my $names (@NAMES)
{
foreach my $families (@FAMILIES)
{
print "$names, // $families\n";
}
}
预期结果:
ALLIES, // A
ALLIES, // B
ALLIES, // C
BOBBY, // A
BOBBY, // B
BOBBY, // C
CAKRA, // A
CAKRA, // B
CAKRA // C
答案 0 :(得分:2)
我看不到有一种优雅简洁的方法,因为您需要将逗号放在两个数组的最后一个元素上。然后添加一个显式条件,同时遍历索引,以便能够挑选出最后一个元素
use warnings;
use strict;
use feature 'say';
my @names = qw(ALLIES BOBBY CAKRA);
my @families = qw(A B C);
for my $n (0..$#names) {
for my $f (0..$#families) {
say $names[$n],
( ($n == $#names and $f == $#families) ? ' // ' : ', // '),
$families[$f];
}
}
三元运算符( ? : )
条件下的括号必须具有优先级。另一种方法是使用&&
而不是and
,这样可以更紧密地绑定,但是我不想让代码依赖
具体的运算符。
语法$#ary
用于@ary
的最后一个元素的索引。
答案 1 :(得分:1)
通常使用join
是最好的答案,但这仅在您要防止在行尾使用逗号时才有效。 (至少对于简单的答案,我确定您可以破解它。)
您可以在$#array_name
循环中使用Perl的for
变量来检查您是否位于两个列表的末尾,例如:
#!/usr/bin/perl
use strict;
use warnings;
my @names = qw(ALLIES BOBBY CAKRA);
my @families = qw(A B C);
for my $i (0..$#names) {
for my $j (0..$#families) {
print "$names[$i]" . ($i == $#names && $j == $#families ? ' ' : ', ') . "// $families[$j]\n";
}
}
此外,还请注意样式:《 Perl样式指南》(尝试perldoc perlstyle
)建议仅在使用全大写字母的变量名称为常量时使用它们。这没什么大不了的,而且绝对不是必需的,但是它可以使其他人更轻松地遵循您的代码。 :)
答案 2 :(得分:1)
特殊外壳的最后一个元素总是很杂乱,需要权衡取舍,您最终只能选择对您来说看起来不太坏的一个。
与@zdim的完美解决方案相比,这是另一种选择。
请注意,在执行过程中,我将更改@names和@families,需要进行更多的权衡,如果有问题,则可以轻松地复制数组。
#!/usr/bin/perl
use strict;
use warnings;
my @names = qw(ALLIES BOBBY CAKRA);
my @families = qw(A B C);
my $last_name = pop(@names);
foreach my $names (@names)
{
foreach my $families (@families)
{
print "$names, // $families\n";
}
}
my $last_family = pop(@families);
foreach my $families (@families)
{
print "$last_name, // $families\n";
}
print "$last_name // $last_family\n";
答案 3 :(得分:1)
另一种选择是将输出与跨产品生成分开,并专门处理最后的演员表。
my @cross_product;
for my $n (0..$#names) {
for my $f (0..$#families) {
push @cross_product, [ $n, $f ];
}
}
if (@cross_product) {
say "$_->[0], // $_->[1]" for @cross_product[0..@cross_product-2];
say "$_->[0] // $_->[1]" for $cross_product[-1];
}
您甚至可以避免用尽以下所有内存:
use Set::CrossProduct qw( );
my $i = Set::CrossProduct->new([ \@names, \@families ]);
my $N = $i->cardinality;
say sprintf '%1$s%3$s // %2$d', $i->get(), $_?',':'' for -$N+1..0;
答案 4 :(得分:1)
我想到了池上的一个变种(将结果存储在一个临时数组中)。可能会有太多更改以至于无法容纳在评论中,所以在这里:
您也可以将逗号存储到临时列表中,然后仅将其从最后一行中删除。
#!/usr/bin/perl
use strict;
use warnings;
my @names = qw(ALLIES BOBBY CAKRA);
my @families = qw(A B C);
my @output_lines;
foreach my $name (@names) {
foreach my $family (@families) {
push @output_lines, [$name, ',', ' // ' . $family . "\n"];
}
}
if (@output_lines) {
$output_lines[-1][1] = ''; # remove comma from last line
print map { @$_ } @output_lines;
}