1

考虑以下脚本:

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_ref

routine1打印以下内容:

$VAR1 = [
         '1A',
         '2A',
         'one_A'
        ];

routine2打印如下:

$VAR1 = [
         [
           '1',
           '2'
         ],
         'one'
        ];

我想继续使用@_and arr_refinroutine2但想得到以下输出:

$VAR1 = [
         '1',
         '2'
         'one'
        ];

有人可以建议出路吗?

4

3 回答 3

3

使用该函数ref,您可以查看标量是否为引用(如果是,则为哪种类型)。在仅传递数组引用的简单情况下,您可以简单地使用它来展平输入。

#!/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 ); 

当然,要使用哪些处理取决于您的用例。

于 2013-03-30T18:42:48.687 回答
1

前几天上班写的。

sub flatten {
    return map { ref($_) ? flatten(@{$_}) : ($_) } @_;
}
于 2013-03-31T05:48:05.110 回答
0

该程序显示了一个子例程flatten,它将扁平化简单数据和数组引用的混合列表,嵌套到任何级别。

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;
    }
  }
  @_;
}

输出

["1A", "2A", "one_A"]
[1, 2, "one"]
于 2013-03-30T22:13:55.217 回答