我有以下地图:
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
假设它们具有相等的键,并用另一个覆盖其中一个。
你可以(在某种程度上(通过改变比较函数来解决这个问题,使其具有严格的排序;也就是说,如果'date
s相等,则按关键字排序:
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'])));