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
Set<Id>? Is the best option just a for loop?
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.
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.
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());`
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.
@jonathanwiesel you have to use a loop and put each key individually in that case. No tricks I know of there.