Perl 如何将子程序的参数展平到数组中?
考虑以下脚本:Perl 如何将子程序的参数展平到数组中?,perl,Perl,考虑以下脚本: use strict; use Data::Dumper; my @arr=('1A','2A'); my $arr_ref=['1','2']; sub routine1 { my @arr=@_; print Dumper(\@arr); } routine1(@arr,'one_A'); sub routine2 { my $arr_ref=[@_]; print Dumper($arr_ref); } routine2($arr_ref,'one'); rou
use strict;
use Data::Dumper;
my @arr=('1A','2A');
my $arr_ref=['1','2'];
sub routine1
{
my @arr=@_;
print Dumper(\@arr);
}
routine1(@arr,'one_A');
sub routine2
{
my $arr_ref=[@_];
print Dumper($arr_ref);
}
routine2($arr_ref,'one');
routine1
正在使用@arr
,routine2正在使用$arr\u ref
routine1
打印以下内容:
$VAR1 = [
'1A',
'2A',
'one_A'
];
$VAR1 = [
[
'1',
'2'
],
'one'
];
routine2
打印以下内容:
$VAR1 = [
'1A',
'2A',
'one_A'
];
$VAR1 = [
[
'1',
'2'
],
'one'
];
我想继续在routine2
中使用@
和arr\u ref
,但想得到以下输出:
$VAR1 = [
'1',
'2'
'one'
];
有人能提出解决办法吗?使用该函数,您可以看到标量是否是引用(如果是,则是哪种类型)。在只传递数组引用的简单情况下,您可以简单地使用它来展平输入
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
sub test {
my @arr = map { ref() ? @$_ : $_ } @_;
print Dumper \@arr;
}
test( ['a', 'b'], 1 );
另一个好处是,如果传递了对另一种类型的引用,则此代码将随消息一起消失,因为您尝试将遵从性作为数组。如果需要处理更多,则需要检查引用类型。这很快就开始变得复杂起来
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
sub test {
my @arr = map {
my $type = ref;
if ( ! $type ) {
$_;
} elsif ( $type eq 'ARRAY' ) {
@$_;
} elsif ( $type eq 'HASH' ) {
%$_;
} else {
()
}
} @_;
print Dumper \@arr;
}
test( ['a', 'b'], { p => 'q' }, 1 );
通过返回其他引用类型的空列表,我会自动忽略所有其他引用类型。或者您更愿意对其他引用类型强制严格化
...
} else {
"$_";
}
...
test( ['a','b'], sub{}, bless({},'MyClass'), 1 );
当然,使用哪种句柄取决于您的用例。使用该函数,您可以查看标量是否为引用(如果是,则为哪种类型)。在只传递数组引用的简单情况下,您可以简单地使用它来展平输入
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
sub test {
my @arr = map { ref() ? @$_ : $_ } @_;
print Dumper \@arr;
}
test( ['a', 'b'], 1 );
另一个好处是,如果传递了对另一种类型的引用,则此代码将随消息一起消失,因为您尝试将遵从性作为数组。如果需要处理更多,则需要检查引用类型。这很快就开始变得复杂起来
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
sub test {
my @arr = map {
my $type = ref;
if ( ! $type ) {
$_;
} elsif ( $type eq 'ARRAY' ) {
@$_;
} elsif ( $type eq 'HASH' ) {
%$_;
} else {
()
}
} @_;
print Dumper \@arr;
}
test( ['a', 'b'], { p => 'q' }, 1 );
通过返回其他引用类型的空列表,我会自动忽略所有其他引用类型。或者您更愿意对其他引用类型强制严格化
...
} else {
"$_";
}
...
test( ['a','b'], sub{}, bless({},'MyClass'), 1 );
当然,使用哪种处理取决于您的用例。此程序显示一个子例程
展平
,它将展平嵌套到任何级别的简单数据和数组引用的混合列表
use strict;
use warnings;
use Data::Dump;
my @arr = qw/ 1A 2A /;
my $arr_ref = [1, 2];
sub flatten;
routine1(@arr, 'one_A');
routine2($arr_ref, 'one');
sub routine1 {
my @arr=@_;
dd \@arr;
}
sub routine2 {
my $arr_ref = [flatten @_];
dd $arr_ref;
}
sub flatten {
my $i = 0;
while ($i < @_) {
my $item = $_[$i];
if (ref $item eq 'ARRAY') {
splice @_, $i, 1, @$item;
}
else {
++$i;
}
}
@_;
}
此程序显示一个子例程
展平
,它将展平嵌套到任何级别的简单数据和数组引用的混合列表
use strict;
use warnings;
use Data::Dump;
my @arr = qw/ 1A 2A /;
my $arr_ref = [1, 2];
sub flatten;
routine1(@arr, 'one_A');
routine2($arr_ref, 'one');
sub routine1 {
my @arr=@_;
dd \@arr;
}
sub routine2 {
my $arr_ref = [flatten @_];
dd $arr_ref;
}
sub flatten {
my $i = 0;
while ($i < @_) {
my $item = $_[$i];
if (ref $item eq 'ARRAY') {
splice @_, $i, 1, @$item;
}
else {
++$i;
}
}
@_;
}
前几天在工作时写的
sub flatten {
return map { ref($_) ? flatten(@{$_}) : ($_) } @_;
}
前几天在工作时写的
sub flatten {
return map { ref($_) ? flatten(@{$_}) : ($_) } @_;
}
你的问题对我来说太模糊了。你的问题对我来说太模糊了。在子例程中,我们不能直接在数组引用中(而不是在@arr中)获取@uu的值吗?这是可能的吗?为了平展引用,您必须遍历结构。我想你可以试着把它装回@uu,但你为什么要这么做?为什么不干脆
map$\uu,@
?@Zaid,因为那样不行。你试过了吗?在子例程中,我们不能直接在Array_引用中(而不是在@arr中)获取@_的值吗?这是可能的吗?为了平展引用,您必须遍历结构。我想你可以试着把它装回@uu,但你为什么要这么做?为什么不干脆map$\uu,@
?@Zaid,因为那样不行。你试过了吗?数组在一个标量上定义。我很难看出这比一个简单的map@$\uuz,@
@zaid能买什么好。好吧,它可以展平异构列表,也可以展平嵌套更深的列表。换句话说,它在(5、[6]、[7,8]、[9,4]、[5])
@darch:Joel让我意识到,我很难看到这会在一个简单的地图上买到什么。换句话说,它在(5[6],[7,8],[9,4,5])
@darch:Joel让我意识到了这一点