我可以将这个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 :(得分:3)
我是(可读)map-grep链的忠实粉丝。尽管如此,虽然我知道
map越来越多地处理在void上下文中使用的更好,我不喜欢使用
在void上下文中 map 。除此之外,我更喜欢哈希切片来填充内容
数组。如果查找的值不是undef
,那么请点击全部
哈希切片中定义的值应该与grep
一样有效
那些exist
然后将它们转换为查找值。
所以我提供了这个map
解决方案:
map {
$_->{sponsors}
= [ grep {; defined } @lookup{ split( /\s*,\s*/, $_->{sponsors} ) } ]
;
}
grep { $_->{sponsors} && !ref $_->{sponsors} } @events
;
此处使用map
的问题在于,您不是要从另一个项目创建一个项目列表。您正在更新一个列表。
就我的偏好而言,你也可以轻松地做一个fore-foreach:
do {
$_->{sponsors}
= [ grep {; defined } @lookup{ split( /\s*,\s*/, $_->{sponsors} ) } ]
;
}
foreach { $_->{sponsors} && !ref $_->{sponsors} } @events
;
但这与你原来的并没有什么不同。你可以轻松地把那个foreach放在顶部。但然后你有一个循环,我也没有next
的问题。我认为可以获得的最大收益是使用散列片而不是grepping并映射到相同的值。
答案 1 :(得分: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 ];
}
答案 2 :(得分:0)
没有尝试过,但它应该是:
my $event;
push( @{ $event->{sponsors} },
map { $lookup{$_} }
grep { $lookup{$_} }
split( /\s*,\s*/, $event->{sponsors} )
grep { $_->{sponsors} && $event = $_ } @events);