2013-11-14 77 views
3

我可以將這個Perl結合到一個map-grep鏈嗎? 有點聲音說我應該可以,但我不知道該怎麼做!我可以將這個Perl結合到一個map-grep鏈嗎?

# expand sponsor keys in to a list of sponsor objects. 
foreach my $event (@events) { 
    next unless exists $event->{sponsors} && ! ref $event->{sponsors}; 
    $event->{sponsors} = 
    [ map { $lookup{$_} } 
     grep { exists $lookup{$_} } 
      split(/\s*,\s*/, $event->{sponsors}) ]; 
} 

回答

0

還沒有嘗試過,但它應該是沿着線:

my $event; 
push(@{ $event->{sponsors} }, 
     map { $lookup{$_} } 
      grep { $lookup{$_} } 
      split(/\s*,\s*/, $event->{sponsors}) 
       grep { $_->{sponsors} && $event = $_ } @events); 
+0

將無法​​工作。該代碼將字符串「$ event - > {sponsor}」替換爲數組的引用。您不能簡單地將現有值視爲數組引用。 – ikegami

3

我的(可讀)地圖的grep鏈的大風扇。儘管如此,雖然我知道 地圖越來越多地處理在無效的情況下使用,我不喜歡在無效的情況下使用 地圖。除此之外,我更喜歡哈希切片來挑選 中的某個數組。假設查找值不是undef,則從散列片段中刪除所有 定義的值應該可以工作得很好,而對於則應該工作得很好,然後將其轉換爲查找值。

所以我提供此,map解決方案:

map { 
    $_->{sponsors} 
     = [ grep {; defined } @lookup{ split(/\s*,\s*/, $_->{sponsors}) } ] 
     ; 
} 
grep { $_->{sponsors} && !ref $_->{sponsors} } @events 
; 

在這裏使用map的問題是,你沒有創建從其他項目中的一個列表。你是更新一個列表。

至於我的喜好去,你可以很容易地做一做的foreach還有:

do { 
    $_->{sponsors} 
     = [ grep {; defined } @lookup{ split(/\s*,\s*/, $_->{sponsors}) } ] 
     ; 
} 
foreach { $_->{sponsors} && !ref $_->{sponsors} } @events 
; 

但是,這並不是從原來的不同。而且你可以輕鬆地把這個foreach放在最前面。但然後你有一個循環,我也沒有問題與next那裏要麼。我認爲可以取得的最大收益是散列片而不是映射到相同的值並映射到相同的值。

1

我個人認爲,一個簡單的foreach會比使用map/grep更具可讀性:

foreach my $event (@events) { 
    next unless exists $event->{sponsors} && ! ref $event->{sponsors}; 

    my @sponsors; 
    foreach my $sponsor (split /\s*,\s*/, $event->{sponsors}) { 
     push @sponsors, $sponsor if exists $lookup{$sponsor}; 
    } 

    $event->{sponsors} = [ @sponsors ]; 
} 
相關問題