List perl:grep和map在一个操作中

List perl:grep和map在一个操作中,list,perl,List,Perl,在perl中,有没有一种方法可以在单个操作中执行grep和map?类似于python执行列表理解的方式: files = [{ 'path':'/path/to/file1', 'size':123}, { 'path':'/path/to/file2', 'size':987}, { 'path':'/path/file3', 'size':1234}, { 'path':'

在perl中,有没有一种方法可以在单个操作中执行
grep
map
?类似于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;
有没有一种简单的方法可以在一个操作中运行它,或者我必须使用两个语句(或者一个复合语句)

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

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

my @large_paths = map { $_->{path} } grep ...;
  • $files
    是数组引用,因此
    值$files
    没有意义

  • map BLOCK
    grep BLOCK
    分别比
    map EXPR
    grep EXPR
    慢。如果可以的话,你更喜欢后者

  • my@large\u文件路径=
    映射$\uz->{path},
    grep$\->{size}>1024,
    @$文件;
    
    一条带有
    map{…}grep{…}@$files的语句是执行此操作的“标准”方法,与您在Python中执行的操作最接近

    从技术上讲,可以在单个
    map
    中执行此操作,因为
    map
    可以为每个输入值返回任意数量的值,包括零-因此您可以执行类似

    映射{$\>{size}>1024?$\>{path}:()}@$文件
    ,但这实际上不太清晰,我一般不推荐使用。

    如果需要,只需调用
    映射即可

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

    但是我认为一个组合的
    map
    /
    grep
    更清晰。

    values$files
    与实验性(但现在已弃用)功能一起工作,该功能可以自动取消引用变量
    grep{$\u->{size}>1024}$个文件。。。这可能会让你伤心。您需要像在
    @$files
    中一样取消引用
    $files
    ,或者使用我最喜欢的新语法
    $files->@*