I have a SplayTreeMap
of players with their levels, and I wanna print a ranking of these players based on their level.
When I use .forEach
to iterate over this SplayTreeMap
, it ignores the players with the same level (means that while looping over SplayTreeMap
, it doesn't take into consideration values with duplicated keys).
Here is my code:
SplayTreeMap<int, String> map = SplayTreeMap<int, String>();
map[5] = 'player1';
map[2] = 'player2';
map[6] = 'player3';
map[7] = 'player4';
map[7] = 'player5';
map[7] = 'player6';
map.forEach((level, player) {
print('$player -> $level');
});
Here is the output of this code:
player2 -> 2
player1 -> 5
player3 -> 6
player6 -> 7
So I'm asking myself why it doesn't print player4
and player5
.
If there is no solution to this, what's the best alternative to SplayTreeMap
, to have a map, that's sorted based on its keys
CodePudding user response:
A SplayTreeMap
is a type of Map
, and Map
s cannot have duplicate keys:
There is a finite number of keys in the map, and each key has exactly one value associated with it.
(There are Map
-like classes such as package:quiver
's Multimap
, but they cannot derive from Map
since they must provide a different signature for some methods (e.g. operator []
).)
If you want a SplayTreeMap
with multiple values for a single key, then you should store List
s as the values. For example:
import 'dart:collection';
extension SplayTreeMultiMapExtension<K, V> on SplayTreeMap<K, List<V>> {
void add(K key, V value) {
(this[key] ??= []).add(value);
}
}
void main() {
var map = SplayTreeMap<int, List<String>>();
map.add(5, 'player1');
map.add(2, 'player2');
map.add(6, 'player3');
map.add(7, 'player4');
map.add(7, 'player5');
map.add(7, 'player6');
map.forEach((level, players) {
for (var player in players) {
print('$player -> $level');
}
});
}
Prints:
player2 -> 2
player1 -> 5
player3 -> 6
player4 -> 7
player5 -> 7
player6 -> 7
Note that the above implementation allows duplicate players within each level. If you don't want that, you can use a Set<String>
instead of a List<String>
, or you can use a SplayTreeSet<String>
if you want the players to be sorted within each level.