How can I efficiently generate a Set<Id> from a List<SObject> structure?

  • I have a bit of code where I've written a SOQL query that returns a list of SObject records, however I need a Set<Id> structure to pass to another method that I don't have control of (and thus can't change the method signature of).

    How can I turn my returned List<SObject> into a Set<Id>? Is the best option just a for loop?

    don't go with the for loop, use a map constr... oh, nevermind :P

  • ca_peterson

    ca_peterson Correct answer

    8 years ago

    This trick only works on the Id field, but you can use the Map constructor that accepts an SObject list to do this without consuming a script statement for each element in the List.

    For example:

    List<SObject> results = Database.query(someSOQL);
    Set<Id> resultIds = (new Map<Id,SObject>(results)).keySet();

    What this second line does is create a new Map<Id,SObject> from the results list using a special constructor, and then take the map's set of keys via the keySet() method. Then the map falls out of scope and it's heap space is released, leaving you with a very governor-efficient set.

    greased lightning!

    One thing to watch out for if you need to modify the set... You'll get a `System.FinalException: Collection is read-only` error if you try to add to the resultIds. To get around that you need to create a new set, e.g., `Set resultIds = new Set (new Map(results).keySet());`

    or clone the Set `Set resultIds = (new Map(results)).keySet().clone();`

    Worth noting is that if all that you are doing is using the Set in a bind expression then you can don't need to create the Set and can actually just use the List. For example: `List opps = [Select Id,Name From Opportunity Where AccountId = :[Select Id, Name From Account Limit 100]];` works.

    Any workaround for a field different from the Id one?

    @jonathanwiesel you have to use a loop and put each key individually in that case. No tricks I know of there.

    Thanks @ca_peterson. Your answer helped me..Keep rocking!

    quickest answer ever.

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM

Tags used