简体   繁体   English

perl:grep和map在一个操作中

[英]perl: grep and map in one operation

Is there a way to perform a grep and a map in a single operation in perl? 有没有办法在perl的单个操作中执行grepmap Similar to the way that python can perform list comprehension: 类似于python可以执行列表理解的方式:

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: 在Perl中,我需要执行grep来过滤掉大文件,然后使用map来获取我想要的特定值:

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)? 有一种简单的方法可以在一次操作中运行它,还是我必须使用2个语句(或一个复合语句)?

One statement with map { ... } grep { ... } @$files is the "standard" way to do it and the closest equivalent to what you're doing in Python. 使用map { ... } grep { ... } @$files一个语句是执行它的“标准”方式,也是与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 ,因为map可以为每个输入值返回任意数量的值,包括零 - 所以你可以做类似的事情
map { $_->{size} > 1024 ? $_->{path} : () } @$files map { $_->{size} > 1024 ? $_->{path} : () } @$files , but that's substantially less clear and I wouldn't recommend it in general. map { $_->{size} > 1024 ? $_->{path} : () } @$files ,但这一点不太清楚,我不推荐它。

  1. $files is an array reference, therefore values $files does not make sense. $files是一个数组引用,因此values $files没有意义。

  2. map BLOCK and grep BLOCK tend to be slower than map EXPR and grep EXPR , respectively. map BLOCKgrep BLOCK分别比map EXPRgrep EXPR慢。 Prefer the latter if you can. 如果可以的话,更喜欢后者。

my @large_filepaths =
    map $_->{path},
    grep $_->{size} > 1024,
    @$files;

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 ...;

You can do this with just a call to map if you want 如果需要,只需调用map即可完成此操作

my @large_filepaths = map { $_->{size} > 1024 ? ( $_->{path} ) : ( ) } @$files;

but I think a combined map / grep is clearer. 但我认为组合的map / grep更清晰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM