3

我可以将这个 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} ) ];
}
4

3 回答 3

3

我是(可读的)map-grep 链的忠实粉丝。尽管如此,尽管我知道 map 越来越多地处理在 void 上下文中使用,但我不喜欢在 void 上下文中使用 map。除此之外,我更喜欢哈希切片而不是在数组中查找某些内容。如果查找的值不是undef,则从散列片中 grepping 所有定义的值应该和grep-ing一样工作exist,然后将它们转换为查找值。

所以我提供这个,map解决方案:

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

在这里使用的问题map在于,您没有从另一个项目列表中创建一个项目列表。您正在更新一个列表。

就我的喜好而言,您也可以轻松地做一个 do-foreach :

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

但这与您的原始版本没有什么不同。您也可以轻松地将 foreach 放在顶部。但是你有一个循环,我也没有问题next。我认为可以获得的最大收益是使用哈希切片而不是 grep 并映射到相同的值。

于 2013-11-14T18:14:36.253 回答
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 ];
}
于 2013-11-14T18:53:13.347 回答
0

没试过,但应该是这样的:

 my $event;
 push( @{ $event->{sponsors} }, 
         map { $lookup{$_} }
           grep { $lookup{$_} }
             split( /\s*,\s*/, $event->{sponsors} ) 
               grep { $_->{sponsors} && $event = $_ } @events);
于 2013-11-14T17:44:44.953 回答