はじめに
Comparebleを使ったソート機能が理解できなかったため、
匿名実行で試してみました
Comparebleを使うと何がいいのか
1.自分の設定した項目でソートを実装できる
通常、.sort()するとSalesforceが内部的に定義している順序で並べ替えられます。
例えば取引先を.sort()すると、Name項目で並べ替えられます。
参考:Apex開発者ガイド:sObject のリストの並び替え順序
Comparebleを使えば、
自分が作ったカスタム項目(Age__cのような)などでもソートができるようになります。
apexでは、「SOQLでできることはすべき」という大前提があります。
なので基本SOQLで実装し、どうしてもできないときにComaprebleを使うべきです。
詳しくはこちら記事ご覧ください
https://qiita.com/su063/items/cee37d4570dc59775301
2.複数条件でのソートが可能になる
条件を足せば、例えば
「Nameが同じだったらさらにage__cでソートする」
などの実装が可能になります。
こちらの記事でわかりやすくまとめてありますので、載せておきます↓
3.昇順・降順の切り替えが簡単
下のコード見てもらえればわかると思いますが、
昇順と降順の切り替えがとても簡単です。resultの正負を入れ替えるだけです。
クラスコードと解説
global with sharing class SortableAccount implements Comparable {
public Account acc ;
public Boolean isAsc; // 昇順フラグ
global SortableAccount(Account acc, Boolean isAscending) {
this.acc = acc;
this.isAsc = isAscending; // 受け取った昇順フラグ
}
global Integer compareTo(Object other){
SortableAccount otherAcc = (SortableAccount)other; // 受け取った取引先をSortableAccount型にキャスト
Integer result;
// 昇順の場合、比較元の方が大きければ1を返す
if (this.acc.Name > otherAcc.acc.Name) {
result = 1;
// 比較先が大きければ-1を返す
} else if (this.acc.Name < otherAcc.acc.Name){
result = -1;
// 同じならば0を返す
} else {
result = 0;
}
return isAsc ? result : -result; // 降順の場合は結果を正負逆にする
}
}
解説
〇SortableAccount(Account acc, Boolean isAscending)
→ラップするためのカスタムクラス のイメージ。
Comparableを継承したクラスには、CompareToメソッドが使えるようになる。
ここでは、Comparableを継承したクラスであるSortableAccountをインスタンス化し、ただのAccountをSortableAccount型に変えているイメージ。
それによって、CompareToメソッドを使えるようにしている。
〇 global Integer compareTo(Object other)
ソートを行う際のロジックを設定する部分。
- 並び替えのロジック
ある値に基づいて昇順で並び替えを行う場合、以下の処理を記述すればOKです(降順の場合は逆)
「基準となる値 > 比較対象の値」の場合は"1"を返却 → if(record.Age__c > compareTo.record.Age__c){return 1})
「基準となる値 < 比較対象の値」の場合は"-1"を返却 → if(record.Age__c < compareTo.record.Age__c){return -1}
「リストのインデックスをどちらに動かしたいか」という覚え方で問題ありません。
引用:https://qiita.com/t_yano/items/6cb8650f3faeeaaf5120
中身はあまり意識せず、昇順のときはこう書くんだな~ぐらいの理解でOKです。
匿名実行コード
Boolean sortAscending = true; // ← ここで昇順降順を制御。今回は昇順
// 取引先を取得
List<Account> rawResults = [SELECT Id, Name FROM Account WHERE Name Like '%取引先%' LIMIT 10];
// AccountをSortableAccount型にしてリストに格納
List<SortableAccount> wrappedList = new List<SortableAccount>();
for (Account acc : rawResults){
wrappedList.add(new SortableAccount(acc, sortAscending));
}
// ソート実行。このときSortableAccountクラスのcompareTo()が動いている
wrappedList.sort();
// 中身を確認
for (SortableAccount sa : wrappedList){
System.debug('Sorted Name: ' + sa.acc.Name);
}
結果
昇順に並んでいるのがわかります。
おわりに
今回は単純にNameでsortしてみましたが、
カスタムでするとわかりやすいですね。
参考