使用Dart和Flutter按多字段分组并获取每组最小值的实现方法
Dart多字段分组取最低分实现方案
你可以按照以下步骤实现需求:
- 第一步:定义数据模型,统一存储每条游戏分数记录的字段,提前把字符串格式的分数转为数值,避免后续比较出错
- 第二步:拉取Firebase Realtime Database的
gameRanking节点数据,遍历所有子节点转为模型对象列表 - 第三步:创建临时Map存储分组最低分,以
游戏名_学生名作为唯一分组键,遍历所有记录更新对应分组的最小值 - 第四步:遍历临时Map输出指定格式的结果
完整代码示例
1. 定义数据模型
class GameRankingEntry { final String game; final int score; final String student; GameRankingEntry({ required this.game, required this.score, required this.student, }); // 从Firebase返回的子节点Map转换为模型对象 factory GameRankingEntry.fromMap(Map<String, dynamic> map) { return GameRankingEntry( game: map['game'] as String, // 把字符串类型的score转为int,避免字符串比较逻辑异常 score: int.parse(map['score'] as String), student: map['student'] as String, ); } }
2. 核心分组统计逻辑
void processGameRanking(Map<String, dynamic> gameRankingRawData) { // 把原始数据转成模型列表 List<GameRankingEntry> allEntries = gameRankingRawData.values .map((entryMap) => GameRankingEntry.fromMap(Map<String, dynamic>.from(entryMap))) .toList(); // 存储分组最低分:key为「游戏名_学生名」,value为对应分组的最低分 Map<String, int> groupMinScore = {}; for (final entry in allEntries) { String groupKey = '${entry.game}_${entry.student}'; // 分组不存在或者当前分数比已存分数更低时,更新最低分 if (!groupMinScore.containsKey(groupKey) || entry.score < groupMinScore[groupKey]!) { groupMinScore[groupKey] = entry.score; } } // 输出符合要求的结果 groupMinScore.forEach((key, minScore) { final parts = key.split('_'); final game = parts[0]; final student = parts.sublist(1).join('_'); // 兼容学生姓名包含下划线的场景 print('$game $student $minScore'); }); }
3. 调用示例
void main() { // 这里替换为你从Firebase拉取到的原始gameRanking节点数据 final Map<String, dynamic> rawData = { "-MmvcDgrGsuCjhcsmXfP" : { "game" : "Puzzle", "score" : "105", "student" : "John Doe", }, "-MasdDgrGsuCjhcsmXfP" : { "game" : "Puzzle", "score" : "99", "student" : "John Doe", }, "-Mmw0kagqLrEbdWlkXg7" : { "game" : "Puzzle", "score" : "87", "student" : "Mary Doe", }, "-MmwC8ONbJUWzP_Wa7X0" : { "game" : "Puzzle", "score" : "95", "student" : "Mary Doe", } }; processGameRanking(rawData); }
运行输出
Puzzle John Doe 99 Puzzle Mary Doe 87
如果是通过flutterfire库拉取Firebase数据,直接把DataSnapshot返回的value转为Map<String, dynamic>传入processGameRanking方法即可。
内容的提问来源于stack exchange,提问作者cris gomez
相关产品推荐
相关产品推荐

