業務にて詰まった部分とその解決方法を簡単に紹介
発生した問題
特定の値を基準にして昇順・降順に並び替える方法として package:collection の sorted がとても役に立ちます
例えば、以下のようなMap型の値が存在していたとします
final targetValue = [
{'value1': 1, 'value2': 5, 'value3': 3},
{'value1': 5, 'value2': 4, 'value3': 9},
{'value1': 2, 'value2': 4, 'value3': 5},
{'value1': 4, 'value2': 3, 'value3': 7},
{'value1': 3, 'value2': 3, 'value3': 1},
];
これを value1 の値を基準として昇順に並び替えたい場合は以下のように記述します
targetValue.sorted((a, b) => a[value1].compareTo.b[value1]);
結果はこのようになります
[
{'value1': 1, 'value2': 5, 'value3': 3},
{'value1': 2, 'value2': 4, 'value3': 5},
{'value1': 3, 'value2': 3, 'value3': 1},
{'value1': 4, 'value2': 3, 'value3': 7},
{'value1': 5, 'value2': 4, 'value3': 9},
];
こういった使い方なら意図した順番に並んでくれるでしょう
でも、value2 を基準にした場合はどうでしょうか
targetValue.sorted((a, b) => a[value2].compareTo.b[value2]);
結果はこうなります
[
{'value1': 4, 'value2': 3, 'value3': 7},
{'value1': 3, 'value2': 3, 'value3': 1},
{'value1': 5, 'value2': 4, 'value3': 9},
{'value1': 2, 'value2': 4, 'value3': 5},
{'value1': 1, 'value2': 5, 'value3': 3},
];
同じ数値がある場合、その順番は入れ替えないので、もしかしたら意図しない順番になってしまうかもしれません
解決策
sorted
の挙動と compareTo
の仕様をうまく利用して複数の条件を設定することで求めている順番に並び替えることができます
value2 で比較した後に、同じ値だったら value3 を参照するという指定をする場合は以下のように記述します
targetValue.sorted((a, b) {
final result = a[value2].compareTo.b[value2]);
if (result = 0) return result;
return a[value3].compareTo.b[value3]);
});
結果は以下の通り、value2 が同値の場合は value3 を基準にして並び替えられています
[
{'value1': 3, 'value2': 3, 'value3': 1},
{'value1': 4, 'value2': 3, 'value3': 7},
{'value1': 2, 'value2': 4, 'value3': 5},
{'value1': 5, 'value2': 4, 'value3': 9},
{'value1': 1, 'value2': 5, 'value3': 3},
];
このような処理になる理由として、sorted
と compareTo
の挙動を見ながら確認していきましょう
1.sorted
は指定した値リストから2つの値(a,b)を取り出す
2.a.compareTo.b
でaとbの値を比較し、以下の条件で値を返却する
- aの方が大きかった場合 → 1
- bの方が大きかった場合 → -1
- aとbが同じだった場合 → 0
3.返却した値を元に順番を入れ替えて1巡が終了、次の値を準備して1へ戻る
このように処理しています
つまり、最終的に1
,0
,-1
のどれかを返却することができるなら、条件はいくつあってもいいということなのです
その条件を追加するために判定として 0
を利用します
0
が返却されているということは、同じ値が比較されているということなので、その状態の時に追加の条件で比較するように設定します
追加の条件でも比較が完了しない可能性があるリストの場合は、同様にその下に何行でも条件を追加することができるのです
とても便利に使うことができるので挙動も込みでぜひ覚えておいてください