Flutter中使用SplayTreeMap排序Map时如何避免重复项被删除?
Dart中按date排序Map时保留重复date条目问题解决
问题原因
SplayTreeMap 是有序键值对集合,它的核心判定逻辑是:当自定义比较函数返回0时,会认为两个键是等价的,后添加的等价键会覆盖之前的条目。你只通过date值做比较,当两个键对应的date相等时(比如two和one的date都是2),比较函数返回0,SplayTreeMap就会把这两个键视为同一键,最终只保留一个,导致重复date的项被删除。
解决方案
方案1:修改比较函数,date相同时对比键本身
在排序逻辑里,先按date排序,当date相等时,再对比键的字符串顺序,确保不同键不会被判定为等价:
Map<String, dynamic> data = {'two': {'date' : 2}, 'zero': {'date' : 1}, 'three': {'date' : 3}, 'one': {'date' : 2},}; final sorted = SplayTreeMap<String, dynamic>.from(data, (a, b) { final dateCompare = data[a]["date"].compareTo(data[b]["date"]); if (dateCompare == 0) { // date相同时,按键的字符串顺序区分 return a.compareTo(b); } return dateCompare; }); print(sorted); // 输出:{zero: {date: 1}, one: {date: 2}, two: {date: 2}, three: {date: 3}}
方案2:转为List排序后再转回Map(更灵活)
如果不需要依赖SplayTreeMap的自动排序特性,可以先把Map的键值对转为List,排序后再转回Map(Dart 3.0+的普通Map会保留插入顺序):
Map<String, dynamic> data = {'two': {'date' : 2}, 'zero': {'date' : 1}, 'three': {'date' : 3}, 'one': {'date' : 2},}; // 转为键值对List并排序 final sortedEntries = data.entries.toList() ..sort((entryA, entryB) { final dateCompare = entryA.value["date"].compareTo(entryB.value["date"]); if (dateCompare == 0) { return entryA.key.compareTo(entryB.key); } return dateCompare; }); // 转回有序Map final sortedMap = Map.fromEntries(sortedEntries); print(sortedMap); // 输出:{zero: {date: 1}, one: {date: 2}, two: {date: 2}, three: {date: 3}}
内容的提问来源于stack exchange,提问作者faccio
相关产品推荐
相关产品推荐

