5

ディレクトリ ツリーをステップ実行するプログラムを作成しています (はい、File::Find については知っていますが、代わりのプログラムを作成しています)。

私のプログラムでは、readdirディレクトリ全体に対して実行し、それをリストに配置しています。私は2つのことをする必要があります:

  1. ...をリストから削除する
  2. 各ファイルの現在のディレクトリ名を先頭に追加します。

ループでこれを行うことも、mapandを使用することもできgrepます。

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

grepとの組み合わせはどうmapですか?

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

来週、コードを見て何が起こっているのかを理解しようとするときに、コードを読みやすくしたいと思っています。コードを効率的にする必要もあります。

4

3 に答える 3

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ので、それは別のボーナスです。

于 2011-12-12T19:54:06.553 に答える
2

コードを読みやすくするには、もう1行含める必要があります。

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

:-)

于 2011-12-12T19:49:14.297 に答える
1

代わりにあなたが望むかもしれないように聞こえますglob。だけで.なく、で始まるすべてのファイル(つまり、隠しファイル)を除外すると思いますが もちろん、パスにスペースを含めることはできません。...

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

あなたがそれを養う限り、それは戻ってきます。

于 2011-12-12T20:13:19.503 に答える