前回の続き
Ruby - select + mapを1つのメソッドで - Qiita [キータ]
いわゆる探索のコーディングスタイルについて。
ワイルドカードの使い方を良く知らない人が、指定ディレクトの中から条件に沿うファイル(ファイル名の最後が数値で終わる)を探して配列で返す関数を作りたいとする。
今まではこう書いていた。
def obtain_file_list(path=".", acc=[])
Dir::glob("#{path}/*").each do |child_node|
if FileTest.directory?(child_node)
obtain_file_list(child_node, acc)
else
if child_node =~ /\d$/
acc << child_node
else
acc
end
end
end
acc
end
p obtain_file_list("/usr/local/Cellar")
ただ、eachを使って変数の中身を変更するのがキモい。という価値感が出てきたので、
最近はflat_mapを使用した書き方をするようになってきた。
def obtain_file_list(path=".")
Dir::glob("#{path}/*").flat_map do |child_node|
if FileTest.directory?(child_node)
obtain_file_list(child_node)
else
if child_node =~ /\d$/
child_node
else
[]
end
end
end
end
p obtain_file_list("/usr/local/Cellar")
これだと、変数を一切破壊せずに実行できてキモい。
追記
slimymars がコメント 2日前
外のを壊したくないならEnumerable#injectとか。
なるほど。これはこれで、まだ言語化しにくい違和感が。
def obtain_file_list(path=".")
Dir::glob("#{path}/*").inject([]) do |acc, child_node|
if FileTest.directory?(child_node)
acc + obtain_file_list(child_node)
else
if child_node =~ /\d$/
acc << child_node
else
acc
end
end
end
end
p obtain_file_list("/usr/local/Cellar")