SplayTreeMap在Flutter中订购地图后正在删除重复



我有以下地图:

Map<String, dynamic> data = {'two': {'date' : 2}, 'zero': {'date' : 1}, 'three': {'date' : 3}, 'one': {'date' : 2},};

我想在date之前订购。我正在尝试这个代码:

final sorted = SplayTreeMap<String,dynamic>.from(data, (a, b) => data[a]["date"].compareTo(data[b]["date"]));

输出:

{'two': {'date' : 2}, 'zero': {'date' : 1}, 'three': {'date' : 3}}

如何避免删除重复值("日期":2出现两次,但现在在sorted中只出现一次(?

来自SplayTreeMap文档:

使用构造函数中传递的compare函数比较映射的键,以进行排序和相等。

您的比较函数认为条目'two': {'date' : 2}'one': {'date' : 2}相等,因此SplayTreeMap假设它们具有相等的键,并用另一个覆盖其中一个。

你可以(在某种程度上(通过改变比较函数来解决这个问题,使其具有严格的排序;也就是说,如果'dates相等,则按关键字排序:

final sorted = SplayTreeMap<String, dynamic>.from(data, (a, b) {
var valueA = data[a]?['date'];
var valueB = data[b]?['date'];
if (valueA != null && valueB != null) {
var result = valueA.compareTo(valueB);
if (result != 0) {
return result;
}
} 
return a.compareTo(b);
});

请注意,比较函数是在进行查找时使用的,所以我必须添加一些额外的null检查来处理不存在键的查找。

也就是说,我警告不要使用上述代码SplayTreeMap是指通过Map进行排序。但是,您希望Map排序。这本质上是有问题的,因为Map应该是不可变的(如果其中一个键发生了更改,则查找将中断,因为该值仍将存储在原始位置(,但Map可能会发生更改。使顺序依赖于值也意味着按键查找效率不高。

相反,您最好将Map转换为List,对其进行排序,然后创建一个新的Map:

var sorted = Map.fromEntries(data.entries.toList()
..sort((a, b) => a.value['date'].compareTo(b.value['date'])));

最新更新