0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

sortedを用いた複数条件での並び替えとその挙動

Posted at

業務にて詰まった部分とその解決方法を簡単に紹介

発生した問題

特定の値を基準にして昇順・降順に並び替える方法として package:collectionsorted がとても役に立ちます
例えば、以下のような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},
];

このような処理になる理由として、sortedcompareTo の挙動を見ながら確認していきましょう
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 が返却されているということは、同じ値が比較されているということなので、その状態の時に追加の条件で比較するように設定します
追加の条件でも比較が完了しない可能性があるリストの場合は、同様にその下に何行でも条件を追加することができるのです

とても便利に使うことができるので挙動も込みでぜひ覚えておいてください

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?