从AOA perl中删除一个数组

时间:2013-07-09 13:42:38

标签: perl multidimensional-array

我有一个看起来像这样的数组 -

$VAR1 = [
          'sid_R.ba',
          'PS20TGB2YM13',
          'SID_r.BA',
          'ARS',
          'XBUE'
        ]; $VAR2 = [
          'sddff.pk',
          'PQ10XD06K800',
          'SDDFF.PK',
          'USD',
          'PINX'
        ]; $VAR3 = [
          'NULL',
          'NULL',
          'NULL',
          '.',
          'XNAS'
        ]; $VAR4 = [
          'NULL',
          'NULL',
          'NULL',
          '.',
          'XNAS'
        ]; $VAR5 = [
          'NULL',
          'NULL',
          'NULL',
          'EUR',
          'OTCX'
        ]; $VAR6 = [
          'sid.ba',
          'PS20TGB1TN17',
          'SID.BA',
          'ARS',
          'XBUE'
        ];

如果任何元素为NULL

,我想删除完整的块(数组引用)

我有一个生成数组的代码,所以我尝试使用for循环删除,但是在for循环内部减少了数组的索引。

所以我不知道数组的顺序或数组的长度。 我需要一个通用的解决方案。

请帮忙。

由于

6 个答案:

答案 0 :(得分:7)

你似乎有一个类似

的数组
my @AoA = (
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, "NULL"],
  [9, 10],
);

您想要选择不包含"NULL"的所有子数组。简单:只需使用嵌套的grep

my @AoA_sans_NULL = grep {
  not grep { $_ eq "NULL" } @$_
} @AoA;

grep { CONDITION } @array选择@array评估为真的CONDITION中的所有元素。

grep { $_ eq "NULL" } @$_计算内部数组中"NULL"的数量。如果这是零,我们的条件为真,否则,我们不想保留该子数组。

答案 1 :(得分:5)

    use List::MoreUtils qw(none);
    my @filtered = grep {
      none { $_ eq "NULL" } @$_;
    } @array;

答案 2 :(得分:2)

这样做你想要的吗?

my @new_array = grep { scalar(grep { $_ eq 'NULL' } @{$_}) == 0 } @old_array;

答案 3 :(得分:0)

旧学校:

my @filtered = ();

ARRAY_LOOP:
for my $array ( @AoA ){

  ITEM_LOOP:
  for my $item ( @$array ){

    next ARRAY_LOOP if $item eq 'NULL';

  } # end ITEM_LOOP

  push @filtered, $array;

} # end ARRAY_LOOP

答案 4 :(得分:0)

此代码将比其他代码慢,但如果数据集非常大,则就地解决方案可能会有用。

use List::MoreUtils qw(any);
for(my $i = 0; $i < @AoA; $i ++) {
    splice @AoA, $i --, 1
        if any { $_ eq "NULL" } @{ $AoA[$i] };
}

答案 5 :(得分:0)

grep解决方案的非grep

my @array = ...;  #Array of Arrays
for my $array_index ( reverse 0 .. $#array ) { 
    my @inner_array = @{ $array[$array_index] };
    if ( grep /^NULL$/, @inner_array ) {
        splice @array, $array_index, 1;
    }
}
say Dumper @array;

splice命令删除整个子阵列。我不需要创建@inner_array我可以在if语句中使用我的解除引用的@{ $array[$array_index] },但我希望明白这一点。

唯一的问题是你必须向后浏览你的数组。如果从第一个元素到最后一个元素遍历数组,则将删除元素2,这会导致所有其他元素的索引减少。如果我先删除元素4,则元素0到3不会改变它们的索引。

它不像<{1}}解决方案的grep 优雅,但它更容易维护。想象一下,有人必须在六个月后完成你的计划,试图弄明白:

grep

正在做。