ListViewでは、Mapの状態では使用することができないので MapEntry化する必要がある。
userModel.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
part 'userModel.freezed.dart';
part 'userModel.g.dart';
@freezed
class UserModel with _$UserModel {
const factory UserModel({
@Default("") String name,
@Default("") String age,
}) = _UserModel;
factory UserModel.fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
}
List<UserModel> users = [
UserModel(name:"Ichiro", age:"29"),
UserModel(name:"Jiro", age:"33"),
UserModel(name:"Saburou", age:"29"),
UserModel(name:"Sirou", age:"33"),
UserModel(name:"Gorou", age:"21"),
UserModel(name:"Rokurou", age:"60"),
]
上記のようなモデル構造User、及びそれらを配列で持つusersがあるとします。
まずは、下記のように年齢ごとにマップ化する関数を定義します。
//このようにしたい。
{
"29":
[
UserModel(name:"Ichiro", age:"29")
UserModel(name:"Saburou", age:"29"),
],
"33":
[
UserModel(name:"Jiro", age:"33"),
UserModel(name:"Sirou", age:"33"),
],
"21":
[
UserModel(name:"Gorou", age:"21"),
],
"60":
[
UserModel(name:"Gorou", age:"21"),
],
}
//関数定義
Map<String, List<UserModel>> _makeGroupByAgeMap(
List<UserModel> userModelList) {
Map<String, List<UserModel>> _groupByAgeMap = {};
for (UserModel userModel in userModelList) {
//ループしてきたuserModelのageでまだグループ化してない場合は先に空配列を代入する。
_groupByAgeMap[userModel.age] ??= [];
_groupByAgeMap[userModel.age]!.add(userModel);
}
return _groupByAgeMap;
}
ListViewはマップのままでは表示できないので、MapEntry化する必要がある。
//関数定義
List<MapEntry<String, List<UserModel>>> _makeMapEntryListPerAge(
Map<String, List<UserModel>> _groupByAgeMap) {
List<MapEntry<String, List<UserModel>>> _listPerAge = [];
_groupByAgeMap.forEach((key, value) {
_listPerAge.add(MapEntry(key, value));
});
return _listPerAge;
}
//最初に呼び出す関数
List<MapEntry<String, List<UserModel>>> getMapEntrysGroupByAge(
List<UserModel> userModelList) {
//ListをGroupByしたMapにする。
Map<String, List<UserModel>> _groupByAgeMap =
_makeGroupByAgeMap(userModelList);
//MapEntry化してListに格納する。
List<MapEntry<String, List<UserModel>>> _listPerAge =
_makeMapEntryListPerAge(_groupByAgeMap);
return _listPerAge;
}