2013-11-14 45 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 ]; 
} 
相关问题