In python, I can do the following to get all the objects in a list with a specific property. In this example I grab the list of id
fields of every obj
in list objs
where obj.id
is greater than 100:
ids = [ obj.id for obj in objs if obj.id > 100]
How would I do the same in perl? I think I want to use map
, but I don't know how to conditionally map items from the origin set to the destination set.
The map
block can return 0 or more elements for each element in the original list. To omit an element, just return the empty list ()
:
my @ids = map { $_->id > 100 ? $_->id : () } @objs;
This assumes that the objects in @objs
have an id
attribute and associated accessor. If you want direct hash access, you can do that too:
my @ids = map { $_->{id} > 100 ? $_->{id} : () } @objs;
Or, you can just combine map
and grep
:
my @ids = map { $_->id } grep { $_->id > 100 } @objs;
# Or reverse the order to avoid calling $_->id twice:
my @ids = grep { $_ > 100 } map { $_->id } @objs;
I'm not sure which of those would be more efficient, but unless @objs
is really big, that's unlikely to matter much.
If the value you're extracting from the object is expensive to calculate, then you can cache the value for the test and return value:
my @vals = map { my $v = $_->expensive_method; $v > 100 ? $v : () } @objs;
Use grep
to return only those items that match the condition. It's like filter
in other languages.
grep
{ condition }
@array
For example:
my @nums = (1, 50, 7, 105, 200, 3, 1000);
my @numsover100 = grep { $_ > 100 } @nums;
foreach my $num (@numsover100) {
print $num . "\n";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With