Reputation: 21493
Is there a way to perform a grep
and a map
in a single operation in perl? Similar to the way that python can perform list comprehension:
files = [{ 'path':'/path/to/file1',
'size':123},
{ 'path':'/path/to/file2',
'size':987},
{ 'path':'/path/file3',
'size':1234},
{ 'path':'/path/to/file4',
'size':543},
{ 'path':'/path/to/my/file5',
'size':1357}]
large_filepaths = [file['path'] for file in files if file['size'] > 1024]
In Perl, I need to do a grep
to filter out the large files, then a map
to get the specific values I want:
my $files = [ { path=>'/path/to/file1',
size=>123},
{ path=>'/path/to/file2',
size=>987},
{ path=>'/path/file3',
size=>1234},
{ path=>'/path/to/file4',
size=>543},
{ path=>'/path/to/my/file5',
size=>1357} ];
my @large = grep { $_->{size} > 1024 } $files;
my @large_filepaths = map { $_->{path} } @large;
Is there a simple way to run this in a single operation, or do I have to use 2 statements (or one compound statement)?
Upvotes: 3
Views: 3524
Reputation: 126742
You can do this with just a call to map
if you want
my @large_filepaths = map { $_->{size} > 1024 ? ( $_->{path} ) : ( ) } @$files;
but I think a combined map
/grep
is clearer.
Upvotes: 2
Reputation: 240472
One statement with map { ... } grep { ... } @$files
is the "standard" way to do it and the closest equivalent to what you're doing in Python.
Technically it's possible to do it in a single map
, because map
can return any number of values for each input value, including zero — so you can do something like
map { $_->{size} > 1024 ? $_->{path} : () } @$files
, but that's substantially less clear and I wouldn't recommend it in general.
Upvotes: 10
Reputation: 118156
$files
is an array reference, therefore values $files
does not make sense.
map BLOCK
and grep BLOCK
tend to be slower than map EXPR
and grep EXPR
, respectively. Prefer the latter if you can.
my @large_filepaths =
map $_->{path},
grep $_->{size} > 1024,
@$files;
Upvotes: 4
Reputation: 339965
Is there a simple way to run this in a single operation,
You can do it as one compound statement:
my @large_paths = map { $_->{path} } grep ...;
Upvotes: 2