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.

If I have a StandardSetController and an object ID, is there a way to check whether the object would be included in the StandardSetController, short of looping through all of its objects? Best described by example:

String query = 'SELECT Id, Name FROM Account
                WHERE SomeCriteria = :someValue
                ORDER BY AnotherField';
StandardSetController ssc = new StandardSetController(query);

Account thisAccount = howeverYouGetTheAccount();

// Question 1: Is this account included in the SetController?
Boolean isAccountInSet = ???;

// Bonus 2: On what page of results or in what index?
Integer page = ???;
Integer index = ???;

ssc.setPageNumber(page);
List<Account> records = ssc.getRecords();
System.AssertEquals(thisAccount.Id, records.get(index).Id);

Again, I know I could iterate through all the results... but that could be thousands of results and is really inefficient.

UPDATES:

  1. A query locator is required in this case, because we might have thousands of results, and a List or Set would overflow the heap.

  2. My example is simplified. In reality, we have about 10 various criteria running on this search, so while I could recreate it and do a binary search for the item in question, that might be a bit messy...

share|improve this question

2 Answers 2

up vote 1 down vote accepted

If you have a list of Sobjects with IDs you can convert it to a map:

list<Account> accs = new list<Account>();
accs.add(new Account(id='001000000000000000'));
map<ID,Account> accmap = new map<ID,Account>(accs);
system.debug(accmap);

or in your case:

 map<ID,Account> accmap = new map<ID,Account>(ssc.getRecords());
 System.Assert(accmap.contains(thisAccount.Id));

There is no simple way to figure out which page the account is on but since you know that the records are sorted by AnotherField you could do a binary search rather than iterating through all of them.

UPDATE: If you are returning thousands of records (multiple pages of results) there is no way to find out what page of results the account record will be in as the standardsetcontroller doesn't actually add the accounts to the list until you get the next page of results.

One other way to test if the result is there is just to re-run the soql query for that one account and see if it returns 0 or 1 rows. I.E.

String query = 'SELECT Id, Name FROM Account
            WHERE SomeCriteria = :someValue AND ID = :thisAccount.ID
            ORDER BY AnotherField';
share|improve this answer

Is using a queryLocator required?

If not, this approach may work. It iterates the list once for index values, but otherwise should perform both your requirement and the bonus. (assuming the list is not modified, thus altering index values)

List<Account> acctList = [SELECT Id
                            , Name
                            FROM Account
                                WHERE SomeCriteria = :someValue
                                ORDER BY AnotherField];

// build a map containing the index values of the list
// and the correlated recordIds
Map<Id, Integer> indexMap = new Map<Id, Integer>();

// temp integer to minimize repeated method calls
Integer resultSetSize = acctList.size();

// add the recordId and the index position to the indexmap
for (Integer i = 0; i < resultSetSize; i++) {
    indexMap.put(acctList[i].id, i);
}

Account thisAccount = howeverYouGetTheAccount();

// Question 1: Is this account included in the SetController?
Boolean isAccountInSet = indexMap.keyset().contains(thisAccount.Id);

// initialize the controller with the list
StandardSetController ssc = new StandardSetController(acctList);

// Bonus 2: On what page of results or in what index?
Integer listSize = ssc.getResultSize();
Integer pageSize = ssc.getPageSize();
Integer totalPages = (listSize + pageSize -1) / pageSize;

Integer recordIndex = indexMap.get(thisAccount.Id);
Integer recordIsOnPage = (recordIndex + pageSize -1) / pageSize;

ssc.setPageNumber(recordIsOnPage);
share|improve this answer
    
Thanks. While this would work at low volumes, I don't think it's a viable option for us at our actual data volume. But I like the approach a lot! –  Benj Jan 17 '13 at 20:25

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.