先日、Map型のソートをしたときに、データが消える現象に遭遇したので、解決方法をメモ。
Map型のソートでデータが消える例
Map<String, int> userAge = {
'Taro' : 10,
'Hanako' : 7,
'Jiro' : 7,
};
SplayTreeMap.from(userAge, (a, b) => userAge[a]!.compareTo(userAge[b]!));
// print結果: {Jiro: 7, Taro: 10}
// ※ Hanako が消えてる!?
ちなみに、SplayTreeMap
の解説は以下参考
なぜMap型のソートでデータが消えるのか?
原因は、compareToメソッド
にありました。
戻り値は以下の通りです。
- aの値がbの値よりも大きい = 1
- aの値とbの値が同じ = 0
- aの値がbの値よりも小さい = -1
例えば、以下のように数値を比較した場合の戻り値を見てみましょう。
// 比較数値 = 戻り値
// 10と7 = 1
// 10と10 = 0
// 7 と10 = -1
このように、値が同じ場合に、データが消えてしまっていたんですね。
Map型のソートでデータを消さない方法
先程の結果から分かる通り、compareToメソッド
の戻り値が 0
にならないようにしましょう。
// 出力結果: {Ariana: 50, Saw: 50, Ichiro: 80}
Map<String, int> userAge = {
'Taro' : 10,
'Hanako' : 7,
'Jiro' : 7,
};
userAge = SplayTreeMap.of(userAge, (a, b) {
int compare = userAge[a]!.compareTo(userAge[b]!);
// compareが 0(aとbの値が同じ場合)なら1(aがbよりも大きい場合)に置き換え
return compare == 0 ? 1 : compare;
});
// print結果: {Hanako: 7, Jiro: 7, Taro: 10}