2018.10.16
ApexでのsObjectソートとNULLの制御
こんにちは!
Apexでオブジェクトのリストを扱う上では欠かせないソート。 デフォルトでは以下4つの順でソートされることはご存知でしょうし、 それ以外のルールでソートしたいときはComparableインターフェースを使用する、 ということも詳しい皆さんのことですから重々承知でしょう。
(4つのソート順)
- sObject型の表示ラベル
- Name項目
- 標準項目(アルファベット順)
- カスタム項目(アルファベット順)
しかし、公式のドキュメントではカスタム並び替え順は単一のキーでしか対応していません。 これは大変もどかしい。 膨大なデータを扱うときはキー1つでは同じ値が出てきたときに困る! 第2キーを使いたい!
そんなあなたのために、今回はcompareToメソッドで第2キーまでのソートに対応する方法をご紹介しましょう。
単一キーでのソート
さてここで1つおさらい。単一キーでのソートは大変シンプル。 以下のようなコードでさっくり実現できます。 今回は取引先を従業員数の昇順でソートしてみましょう。
public class SingleKeySortController {
public List targetAccList{get;set;}
public Boolean isDesc{get;set;}
public SingleKeySortController(){
isDesc = false;
//取引先を取得
List accList = new List();
accList = [SELECT Id, Name, Sic, NumberOfEmployees FROM Account];
//対象をソート
targetAccList = new List();
for(Account ac : accList){
targetAccList.add(new AccDto(ac, isDesc));
}
targetAccList.sort();
}
/**
* ソート用クラス
*/
public class AccDto implements Comparable{
public Account acc{get;set;}
private Integer sortFactor;
//昇順降順を判定
public AccDto(Account ac, Boolean isDesc){
acc = ac;
sortFactor = 1;
if(isDesc){
sortFactor = -1;
}
}
//ソートを実行
public Integer compareTo(Object compareTo) {
AccDto thisDto = (AccDto)compareTo;
//nullを含まない場合
if(this.acc.NumberOfEmployees == thisDto.acc.NumberOfEmployees){
return 0;
}else if(this.acc.NumberOfEmployees > thisDto.acc.NumberOfEmployees){
return sortFactor;
}
return sortFactor*-1;
}
}
}
結果は以下の通り。
従業員数は昇順なのに産業コードは降順でソートされていますね。 どうせなら産業コードも昇順にしたいところです。
複数キーでのソート
さてさて漸くの本題、第2キーを使用したソートです。 と言っても上記の単一キーソートのcompareToメソッドに少し手を加えてやるだけ。実に簡単です。
//ソートを実行
public Integer compareTo(Object compareTo) {
AccDto thisDto = (AccDto)compareTo;
//nullを含む場合
if(this.acc.NumberOfEmployees == null && thisDto.acc.NumberOfEmployees == null){
if(this.acc.Sic > thisDto.acc.Sic){
return sortFactor;
}
if(this.acc.Sic thisDto.acc.Sic){
return sortFactor;
}
if(this.acc.Sic thisDto.acc.NumberOfEmployees){
return sortFactor;
}
return sortFactor*-1;
}
結果は以下の通り
しれっとnullを考慮しているのでnullを含めた従業員数の昇順、 従業員数が同数の場合は産業コードの昇順になっています。スゴイ!
もうひと手間
今回は第2キーまでを利用したsObjectリストのソートを紹介しましたが、 これは応用すればNULLS LASTやNULLS FIRSTの制御、複数オブジェクトのリストソートなども可能です。 それを書くにはこの記事は余りにも狭すぎるのでまたの機会に…… では、オタッシャデー!