0

私はRubyを学んでいますが、暗黙の戻り値全体に問題があります。これが空のベクトルを返す理由を誰か教えてください:

  3 def get_filenames(path)
  4   filenames = []
  5 
  6   if (path == ".") || (path == "..")
  7     []
  8   elsif File.directory? path
  9     Dir.entries(path).each do |sub_path|
 10       filenames += get_filenames(sub_path)
 11     end
 12   else #presumably it's a file
 13     [File.basename(path,".*")]
 14   end
 15 end

引数パスから再帰的に検索したときに見つかったすべてのファイル名 (拡張子を除く) の配列を返す必要があります。

「/tmp」で関数を呼び出し、tmp に「A.txt」と「Bm」の 2 つのファイルと、「C.exe」という 1 つのファイルを含むディレクトリが含まれているとします。この関数が ["A","B","C"] を返すようにしたい

4

5 に答える 5

2

まず第一に、Dir.entries絶対パスを取得しないため、呼び出しを試みるときget_filenames(sub_path)に、相対ファイル名パスを呼び出します (そして、関数は絶対パスを受け取ります)。

これを使って:

def get_files(dir)
   files = []
   Find.find(dir) { |path| files << File.basename(path,".*") if FileTest.file?(path) }
   return files
end
于 2011-01-17T16:40:43.970 に答える
1

クエリの簡単な解決策は次のとおりです...現在のディレクトリとサブディレクトリに存在するすべてのファイルを検索します

{Find.find("", "#{path}") do |file|
 if File.file?(file)
   filenames << file.to_s
 end
end
}
于 2011-01-17T16:27:57.877 に答える
1

if ステートメントには 3 つのパスがあります。最初のものは空の配列を返し、最後のものは配列にラップされた単一の要素を返します。ここまでは順調ですね。

しかし、中間のパスは の値を返しDir.entries、それ自体が で識別されるフォルダのすべてのエントリを返しますpath。イテレータは、それらを再帰的に呼び出してローカル変数に追加するというeach副作用をもたらしますが、 の戻り値は影響を受けません。フォルダ内のすべてのエントリを返します。get_filenamesfilenamesDir.entries

必要な結果を得るにはfilenames、Dir.entries 呼び出しの後に追加するだけです。

于 2011-01-17T20:03:40.803 に答える
0

あなたのif声明が真実であることがわかり、最初のパススルーで終了すると思います。ロジックのその部分を削除するとどうなりますか (に移動elseififif、 とelse?

于 2011-01-17T16:19:31.020 に答える
0

これは私のマシンで期待どおりに動作します。

引数と返された値のそれぞれに print ステートメントを追加して、ケースで実際に何が起こっているかを確認してください。

実際には別の値を渡しているときに、ある値を渡していると考える可能性があります。

于 2011-01-17T16:46:04.343 に答える