perl:grep和map在一个操作中

时间:2017-06-27 16:42:32

标签: list perl

有没有办法在perl的单个操作中执行grepmap?类似于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]

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

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

4 个答案:

答案 0 :(得分:9)

使用map { ... } grep { ... } @$files的一个语句是“标准”方法,它与您在Python中所做的最接近。

从技术上讲,它可以在一个map中完成,因为map可以为每个输入值返回任意数量的值,包括零 - 所以你可以做类似的事情 map { $_->{size} > 1024 ? $_->{path} : () } @$files,但这一点不太明确,我不会推荐它。

答案 1 :(得分:4)

  1. $files是一个数组引用,因此values $files没有意义。

  2. map BLOCKgrep BLOCK分别比map EXPRgrep EXPR慢。如果可以,请更喜欢后者。

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

答案 2 :(得分:2)

  

是否有一种简单的方法可以在一次操作中运行它,

您可以将其作为一个复合语句:

my @large_paths = map { $_->{path} } grep ...;

答案 3 :(得分:2)

如果您想要

,只需拨打map即可完成此操作
my @large_filepaths = map { $_->{size} > 1024 ? ( $_->{path} ) : ( ) } @$files;

但我认为合并的map / grep更清晰。