Perl:使用Loop还是Map / Grep?

时间:2011-12-12 19:44:17

标签: perl map grep readdir

我正在编写一个程序来逐步浏览一个目录树(是的,我知道File :: Find,但我正在编写一个替代品)。

在我的程序中,我在整个目录上执行readdir并将其放在列表中。我需要做两件事:

  1. 从列表中删除...
  2. 在每个文件上添加当前目录名称。
  3. 我可以通过循环执行此操作,或者我可以使用mapgrep

    # Map and Grep
    
    my @dir_stack = readdir $dir_fh;;
    @dir_stack = grep { !/^\.{1,2}$/ } @dir_stack;
    @dir_stack = reverse map { "$cwd/$_" } @dir_stack;
    push @stack, @dir_stack;
    
    # Read Loop
    
    opendir $dir_fh, $cwd;
    my @dir_stack;
    foreach my $file (readdir $dir_fh) {
        next if $file =~ /^\.{1,2}$/;   #Skip "." and ".."
        unshift @dir_stack, "$cwd/$file";
    }
    push @stack, @dir_stack;
    

    如何合并grepmap

     opendir $dir_fh, $cwd;
     my @dir_stack = readdir $dir_fh;;
     @dir_stack = grep { !/^\.{1,2}$/ && {$_ = "$cwd/$_"} } @dir_stack;
     push @stack, reverse @dir_stack;
    

    我想让我的代码在下周看到可读,当我看到它并试图弄清楚发生了什么。我还需要我的代码才能有效。

3 个答案:

答案 0 :(得分:7)

在grep中修改$_?呸!使用anon哈希构造函数有什么用呢?

@dir_stack = grep { !/^\.{1,2}$/ && {$_ = "$cwd/$_"} } @dir_stack;

应该是

@dir_stack = map { /^\.\.?\z/ ? () : "$cwd/$_" } @dir_stack;

但我个人觉得使用map和grep比组合它们更具可读性。

push @stack,
   reverse
    map "$cwd/$_",
     grep !/^\.\.?\z/,
      readdir $dh;

reverse的需求相当奇怪,而且这里比隐藏unshift更加明显,所以这是另一个奖励。

答案 1 :(得分:2)

为了使您的代码更具可读性,您只需要再添加一行:

# exclude '.' and '..', and prepend dir name to each elem in @dir_stack

: - )

答案 2 :(得分:1)

听起来你可能需要glob。虽然我相信它会排除所有以.开头的文件(即隐藏文件),而不仅仅是...。当然,你不能在路径上有空格。

my @stack = glob "$dir_fh/*";

它会在您提供路径时返回。