Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

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?

share|improve this question
2  
don't go with the for loop, use a map constr... oh, nevermind :P –  user320 Feb 26 '13 at 1:24
add comment

2 Answers

up vote 37 down vote accepted

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.

share|improve this answer
    
greased lightning! –  user320 Feb 26 '13 at 1:23
11  
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<Id> resultIds = new Set<Id> (new Map<Id,SObject>(results).keySet()); –  Peter Knolle Feb 26 '13 at 1:27
5  
or clone the Set Set<Id> resultIds = (new Map<Id,SObject>(results)).keySet().clone(); –  Daniel Blackhall Feb 26 '13 at 1:37
1  
Worth noting is that if all that you are doing is using the Set<Id> in a bind expression then you can don't need to create the Set and can actually just use the List<sObject>. For example: List<Opportunity> opps = [Select Id,Name From Opportunity Where AccountId = :[Select Id, Name From Account Limit 100]]; works. –  Peter Knolle Feb 26 '13 at 16:05
add comment

If you are not using Dynamic SOQL, you can skinny this down to a one-liner like this...

Set<Id> ids = (new Map<Id, Lead>([SELECT Id FROM Lead])).keySet();

This is how you would do it with Dynamic SOQL but you must cast...

Set<Id> ids = (new Map<Id, Lead>((List<Lead>)Database.query(query))).keySet();

This unresolved bug is why you must cast the returned List<SObject>

share|improve this answer
1  
Seriously, that issue is still unresolved? I miss Rich Unger so much... –  ca_peterson Feb 26 '13 at 16:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.