Perl相当于Python的嵌入if语句的列表推导?

Ros*_*ers 6 python perl

在python中,我可以执行以下操作来获取具有特定属性的列表中的所有对象.在这个例子中,我抓住名单id的每一个领域obj中的列表objs,其中obj.id大于100:

ids = [ obj.id for obj in objs if obj.id > 100]
Run Code Online (Sandbox Code Playgroud)

我如何在perl中做同样的事情?我想我想使用map,但我不知道如何有条件地将项目从原始集映射到目标集.

cjm*_*cjm 13

map块可以为原始列表中的每个元素返回0个或更多元素.要省略元素,只需返回空列表():

my @ids = map { $_->id > 100 ? $_->id : () } @objs;
Run Code Online (Sandbox Code Playgroud)

这假设对象@objs具有id属性和关联的访问器.如果您想要直接哈希访问,您也可以这样做:

my @ids = map { $_->{id} > 100 ? $_->{id} : () } @objs;
Run Code Online (Sandbox Code Playgroud)

或者,您可以组合mapgrep:

my @ids = map { $_->id } grep { $_->id > 100 } @objs;

# Or reverse the order to avoid calling $_->id twice:
my @ids = grep { $_ > 100 } map { $_->id } @objs;
Run Code Online (Sandbox Code Playgroud)

我不确定哪一个会更有效率,但除非@objs真的很大,否则不太重要.

如果从对象中提取的值计算起来很昂贵,那么可以缓存测试的值并返回值:

my @vals = map { my $v = $_->expensive_method;  $v > 100 ? $v : () } @objs;
Run Code Online (Sandbox Code Playgroud)

  • `图+($ _-> ID)×($ _-> ID> 100),@ objs` (4认同)
  • @ysth:Yikes.我想我会保存那个代码高尔夫球.三元运算符更安全,因为您不必确保条件仅返回0或1. (4认同)