時々とおまわり

プログラミング雑記

複数のファイルを取得して作成日時で並び替える

フィヨルドブートキャンプの課題、Sinatraを使ったメモアプリの開発はまだまだ終わらないです😇 メモ一覧は表示できましたが作成順に並んでいないのが非常に気持ち悪い。 複数のファイルを取得して作成日時で並び替えたいなと思ったので調べてみました。

結論

  1. Dir.glob で指定したディレクトリ内のファイルを配列で取得
  2. File.birthtime でファイル作成日時を取得
  3. sort_by でファイルを並び替える

指定したディレクトリ内のファイルを配列で取得

dir ディレクトリ内の拡張子がjson のファイルを配列で取得する

# ディレクトリ構成

./
├ main.rb
└ dir/
    ├ 1.json
    ├ 2.json
    └ 3.json
# main.rb

files = Dir.glob('./dir/*.json')
p files 

dir ディレクトリ内のファイルが配列として取得できた

$ ruby main.rb
["./dir/1.json", "./dir/2.json", "./dir/3.json"]

ファイル作成日時を取得する

File.birthtime で作成日時を取得

# main.rb

files = Dir.glob('./dir/*.json')
files.each do |file|
  puts "ファイル名: #{file} 作成日時: #{File.birthtime(file)}"
end

ファイル名と作成日時を出力できた

$ ruby main.rb
"ファイル名: ./dir/1.json 作成日時: 2022-06-03 08:39:06 +0900"
"ファイル名: ./dir/2.json 作成日時: 2022-06-03 08:39:17 +0900"
"ファイル名: ./dir/3.json 作成日時: 2022-06-03 08:39:34 +0900"

作成日時以外にも更新日時や最終アクセス日時もFileクラスに用意されている

ファイルの並び替え

Arrayクラスのメソッドで並び替える

  • 昇順: sort_by
  • 降順: sort_by + reverse

ファイルを取得して作成日時で昇順/降順でそれぞれ並び替える

# main.rb

# 昇順
files = Dir.glob('./dir/*.json')

sort_files = files.sort_by { |file| File.birthtime(file) }
reverse_files = files.sort_by { |file| File.birthtime(file)}.reverse

puts "昇順"
sort_files.each do |file|
  puts "ファイル名: #{file} 作成日時: #{File.birthtime(file)}"
end

puts "降順"
reverse_files.each do |file|
  puts "ファイル名: #{file} 作成日時: #{File.birthtime(file)}"
end

昇順、降順でファイルを並び替えて出力できた

$ ruby main.rb
昇順
ファイル名: ./dir/1.json 作成日時: 2022-06-03 08:39:06 +0900
ファイル名: ./dir/2.json 作成日時: 2022-06-03 08:39:17 +0900
ファイル名: ./dir/3.json 作成日時: 2022-06-03 08:39:34 +0900
降順
ファイル名: ./dir/3.json 作成日時: 2022-06-03 08:39:34 +0900
ファイル名: ./dir/2.json 作成日時: 2022-06-03 08:39:17 +0900
ファイル名: ./dir/1.json 作成日時: 2022-06-03 08:39:06 +0900

まとめ

作成日の並び替えの実装を考えた時にファイル作成日時のデータを別に保存する必要がありそうと思っていましたが、File.birthtime だけで実装できてしまったのでめっちゃありがたい! それにしてもFile クラスは本当に奥が深い。またRubyを好きになってしまった!

参照

Dir.[] (Ruby 3.1 リファレンスマニュアル)

Ruby ファイルを読み込む(Dir.globなど)順番について - Qiita

Enumerable#sort_by (Ruby 3.1 リファレンスマニュアル)

Array#reverse (Ruby 3.1 リファレンスマニュアル)