【Flutter】Freezedクラスのリストをソートする
Freezedで定義したカスタムデータモデル(id, name, age)のリストを対象に、id順や年齢順で切り替えて並べ替えられるUIをHooksを使ってサクッと実装してみます!
Freezedクラスの定義
今回はid,年齢,名前のデータのFreezedクラスを生成します。
import 'package:freezed_annotation/freezed_annotation.dart';
part 'model.freezed.dart';
class ApiModel with _$ApiModel{
const factory ApiModel({
required int id,
required String name,
required int age,
}) = _ApiModel;
}
ソートするのはid順と年齢順にします。
今回はデモ用にAIにリストの中身を生成してもらいました。
List<ApiModel> model = [
ApiModel(id: 1, name: '佐藤 花子', age: 18),
ApiModel(id: 2, name: '鈴木 太郎', age: 25),
/*省略*/
ApiModel(id: 10, name: '吉田 彩香', age: 47),
];
ソートの処理
そもそもソートとは...
ソートとは並べ替えのとことを指し、バブルソートやクイックソートなどアルゴリズムとして一つの研究分野になっておりコンピュータサイエンスでは必ず学ぶ基礎のひとつです。
ただし、今回はアルゴリズムを一から実装するのではなくDartに備わっているsort()関数を使って、手軽に並び替え処理を行います。
例えば数字のリストなら..sort()
で昇順に並び替えが可能です。
final numbers = [3, 1, 5, 2];
numbers.sort(); // → [1, 2, 3, 5]
今回は単純なソートではだめな理由は今回は ApiModel というカスタムクラス(名前・年齢などの情報を持つ)をリストにしているためmodel.sort()
だけでは並び替えができません。
final model = [
ApiModel(id: 1, name: '佐藤', age: 30),
ApiModel(id: 2, name: '田中', age: 25),
];
model.sort(); // ❌ エラー!
実装
ソートの処理は..sort()
で並べ替えができます。
List<int>
だと..sort()
で完了しますが前述の通り今回はリストの中に複数のデータが入ってる状態なので()の中にどのデータの順番に並べ替えるかを定義しないとエラーが出てしまいます。
今回はid順ではなく年齢順に並べ替えたいので以下のようにします。
final sortedModel = List<ApiModel>.from(model)..sort((a, b) => a.age.compareTo(b.age));
id順
年齢順
解説
Dartのsort()メソッドには、(a, b) => int という比較関数を渡すことができます。
この関数の戻り値は以下のような意味を持ちます。
- a < b → -1
- a == b → 0
- a > b → 1
今回は年齢(age)で並べたいのでこう書きます。
model.sort((a, b) => a.age.compareTo(b.age));
元の model リストを保持したまま、新しい並び順のリストを作りたい場合は List.from() を使います。
final sortedModel = List<ApiModel>.from(model)
..sort((a, b) => a.age.compareTo(b.age));
おまけ(id順と年齢順を切り替える)
三項演算子とSwitchコンポーネントを使って切り替えを行います。
false
の時はid順でtrue
の時は年齢順にします。
final isChecked = useState(false);
final sortedModel = List<ApiModel>.from(model)
..sort((a, b) =>
isChecked.value ? a.age.compareTo(b.age) : a.id.compareTo(b.id));
Switch(
value: isChecked.value,
onChanged: (value) {
isChecked.value = value;
},
),
id順
年齢順
まとめ
今回はFreezedで定義したデータをソートし、さらにUIから切り替える方法を紹介しました。
ちょっとしたデータ操作や動的な表示切り替えはFlutterで実用的なアプリを作る上で避けては通れません。
Freezedを使えば、安全かつ簡単にデータを扱えるので今後も積極的に使っていこうと思います!
時間があれば、filter機能やsearch機能との組み合わせもやってみたいですね。
Discussion