blog
ブログ

Salesforce技術ブログ: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の制御、複数オブジェクトのリストソートなども可能です。
それを書くにはこの記事は余りにも狭すぎるのでまたの機会に……

では、オタッシャデー!
contact

ご相談・ご質問等ございましたら、お気軽にお問い合わせください。

翻訳