[Tips] SOQLの結果からId型のリストを抽出する

2023.02.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

SalesforceのApexコードにて、SOQLの結果から特定のId項目だけのリストを抽出したいことがあります。

List<Contact> contacts = [
    SELECT
        Id,
        AccountId
    FROM
        Contact
];

// ここでAccountIdだけのリストを取りたい
// 一応、下記のような方法が一般的
List<Id> accountIds = new List<Id>();
for ( Contact contact : contacts ) {
    accountIds.add(contact.AccountId);
}

例示したような方法でも取れるのですが、割と頻繁にある処理なので簡便に使えるようにクラス化しました。

public class FieldSlice {

    private list<Object> olist;

    public FieldSlice(list<Object> olist) {
        this.olist = olist;
    }


    /**
     * 指定したIdフィールドのリストを返す
     * @param idFieldName Idフィールド名
     * @return 指定したIdフィールドのリスト
     */
    public List<Id> retrieveIds(String idFieldName) {
        List<Id> ids = new List<Id>();
        for ( Object obj : olist ) {
            String s = JSON.serialize(obj);
            Map<String,Object> m = (Map<String,Object>)JSON.deserializeUntyped(s);
            // nullは結果から除外
            if ( (Id)m.get(idFieldName) != null ) {
                ids.add((Id)m.get(idFieldName));
            }
        }
        return ids;
    }
}

これを使うと、最初の例は以下のように簡単になります。

List<Contact> contacts = [
    SELECT
        Id,
        AccountId
    FROM
        Contact
];

// ここでAccountIdだけのリストを取りたい
List<Id> accountIds = new FieldSlice(contacts).retrieveIds('AccountId');

// Id項目のリストも取れる
List<Id> Ids = new FieldSlice(contacts).retrieveIds('Id');

SELECTで直接取得しているId型の項目なら使えます。親レコードの項目や子レコードの項目は取れませんので留意してください。