Loop-free way to convert List to List with preserved order

The title says it all. I insert a List into the database and want to pass a list of its Ids in the same order as in the original list. As this test proved using the Map and List constructors does not do the job.

Is there a one-liner so that I don’t have to loop over a list?

List<SObject> sobjectList = new List<SObject>();
sobjectList.addAll(SmartFactory.createSObjectList('Contact', false, 2));
sobjectList.addAll(SmartFactory.createSObjectList('Account', false, 2));
sobjectList.addAll(SmartFactory.createSObjectList('Opportunity', false, 2));
insert sobjectList;

List<Id> idList = new List<Id>(new Map<Id, SObject>(sobjectList).keySet());

for(Integer i=0; i<sobjectList.size(); i++) {
    Id expectedId = sobjectList.get(i).Id;
    Id actualId = idList.get(i);
    System.assertEquals(expectedId, actualId);   
}

Note: When I say preserved order I DO NOT mean alphabetical order or anything like that. I mean it in that way that if SObject S1 is the first in the List, its Id also needs to be the first element in the id list.

Answer

Here goes the WTF…

In theory it has no loops (apart from the display loop). In reality I won’t be surprised if it fails with “regex too complex” error on bigger dataset.

There should be a nicer way with Pattern, Matcher and negative look-behind but I’m too sober for this today…

String text;
List<Account> accs = new List<Account> {
    new Account(Name = 'Acc 1'), 
    new Account(Name = 'Acc 2'), 
    new Account(Name = 'Acc 3')
};

//  text = JSON.serialize(Database.insert(accs));
// if you don't want to insert, just pretend the next line is the result
text = '[{"id":"001A000000zBF1UIAW","success":true,"errors":[]},{"id":"001A000000zBF1VIAW","success":true,"errors":[]},{"id":"001A000000zBF1WIAW","success":true,"errors":[]}]';

text = text.replaceAll('"id":|"success":true|"errors":|\\[|\\]|\\{|\\}|\\"', '').replaceAll(',+', ',').removeEnd(',');
List<String> ids = text.split(',');

if(ids.size() != accs.size()){
    System.debug('Probably save has failed?');
} else {
    for(String s : ids){
        System.debug(s);
    }
}

I suspect it’ll fail horribly when Database.insert(list, false) is used and one of rows fails. Up to you what you want in such scenario, null probably?

Attribution
Source : Link , Question Author : Robert Sösemann , Answer Author : Community

Leave a Comment