2013-07-09 97 views
1

我有陣列的陣列,其看起來像這樣 -移除AOA perl的陣列

$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循環內的數組索引減少。

所以我不知道數組的排列順序或數組長度。 請問我需要一個通用的解決方案。

請幫忙。

感謝

回答

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計算結果爲true。

grep { $_ eq "NULL" } @$_計算內部數組中的"NULL"的數量。如果這是零,我們的條件是真的,否則,我們不想保留該子數組。

+0

我們想出了基本上相同的解決方案,儘管您在解包和解釋它方面做得更好。 –

+0

+1,非常優雅 –

+0

謝謝你!非常感謝。 – Gaurav

2

這是做你想做的嗎?

my @new_array = grep { scalar(grep { $_ eq 'NULL' } @{$_}) == 0 } @old_array; 
5
use List::MoreUtils qw(none); 
    my @filtered = grep { 
     none { $_ eq "NULL" } @$_; 
    } @array; 
+0

你的'沒有任何...'可以寫成'none {$ _ eq「NULL」} @ $ _' – amon

+0

@amn tnx ........ –

+0

這是現在的(恕我直言)最完美的,可能最有效的解決方案 – amon

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 
0

該代碼會比別人慢,但如果數據集是非常大的就地解決方案可能是有用的。

use List::MoreUtils qw(any); 
for(my $i = 0; $i < @AoA; $i ++) { 
    splice @AoA, $i --, 1 
     if any { $_ eq "NULL" } @{ $AoA[$i] }; 
} 
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不會改變它們的索引。

它不像優雅作爲grepgrep解決方案,但它更容易維護。試想一下,誰的人有通過您的計劃已滿6個月,從現在試圖找出什麼去:

grep { not grep { $_ eq "NULL" } @$_ } @array; 

在做什麼。