やりたいこと
通常テーブル内のデータの並び替えをする際は
モデル名.order('カラム名 desc')
等で簡単に実行できます。
しかし今回はテーブル内全体のデータを対象とせずに、あらかじめ特定の条件に合ったレコードのみ配列に入れてあることを前提とします。
例えば以下のような感じ。
users = [
#<User:0x000056357bd5c9b8>
id: 2
name: "たろう",
age: 16,
copuntry: "Japan",
#<User:0x000056357bd5c710>
id: 6
name: "はなこ",
age: 17,
copuntry: "US",
・
・
・
]
この配列に対して並び替えを行いたいが、orderメソッドはそもそもモデルを対象にしか使用できません。
今回は配列にデータを入れてしまっているので、配列のデータの並び替え、しかも特定のカラムの値を対象に並び替えたいです。
試行錯誤の履歴(必要ない方は飛ばしてください)
配列の並び替えだからsort_byメソッドだろうと予測はつきました。
https://ref.xaio.jp/ruby/classes/array/sort_by_bang
●sort_byメソッドの使い方
こちらのRubyリファレンスをそのまま抜粋すると、使用方法は以下のような感じ。
animals = ["mouse", "cat", "hippopotamus", "giraffe"]
p animals.sort_by {|anim| anim.size }
# 出力結果 ==> ["cat", "mouse", "giraffe", "hippopotamus"]
配列animalsの要素を、字数順に並べています。
この配列の場合は、配列の要素が単純なので問題はないんですが、
今回は配列の要素(1つのレコード)のさらに中の、カラムの値を指定して並び替える必要があるので、少し躓いてしまいました。
●そもそも配列に保存されたデータ形式はどうなっているのか
そもそも配列にしたデータは、カラムを指定して特定の要素を呼び出せるのかが不安でした。
配列にしちゃってる時点で、nameやage等のカラム名をカラムとして認識してくれるのかわかりませんでした。
しかし、改めてよく配列を見てみると#<User:0x000056357bd5c9b8>
とある。。
これは、"ちゃんとテーブルのデータとして一つ一つ保存している"に違いない!ということで
試しにコンソールで以下を実施してみました。
users[0][:name]
# 配列usersの1番目のデータを取得し、さらにそのnameカラムを指定してみる
# 出力結果==> "たろう"
ちゃんと拾えました!
データを配列に入れた際、ただの文字列として保存されるのではなく、テーブルのデータとして認識して保存されてるんですね。
多分超基本なんでしょうが、私は今回でやっと認識できました。。
基本すぎてすみません。。配列に関しての理解がまだまだでした。
結果
以上のように色々と試行錯誤した結果、とてもシンプルに実行することができました!
例えばこの記事の一番上の配列usersに対して、ageカラムの値で並び替えしたい場合は、
users.sort_by(&:age)
これだけです!
こうすると、ageの値が小さい順にデータを並び替えることができます。
sort_byメソッドの引数にageを指定するだけでした。
簡単すぎます。