Группировка любого типа в Map

Столкнулся с ситуацией, когда нужно было сгруппировать около 10-ти объектов в Map по 1-ому из полей. У каждого оно имело разное имя, но 1 тип ID.

В начале пошёл напролом и сделал 10 методов под каждый…ужс :upside_down_face::upside_down_face::upside_down_face:

После уже на холодную голову попытался сделать это через sObject. В итоге был приятно удивлён.

Сделал метод, который бы мог принимать и возвращать любой тип. Главное правило: какой тип принял, такой и вернёт, поэтому надо всегда отдавать результат в соответствующий тип. Ещё, так как имена полей отличались, пришлось передавать имя поля, по которому группировать: String fieldName

public Map<Id, List<SObject>> getAnyTypeByParentId(List<sObject> sObjects, String fieldName) {
    Map<Id, List<SObject>> sObjectsMap = new Map<Id, List<SObject>>(); 
    for(sObject so : sObjects) {
        Id soId = (Id)so.get(fieldName);
        if(sObjectsMap.containsKey(soId)) {
            sObjectsMap.get(soId).add(so);
        } else {
            sObjectsMap.put(soId, new List<SObject>{so});
        }
    }

	return sObjectsMap;
}

Так из 10 методов, всё сошлось к 1. :partying_face:

Ниже пример использования такого подхода, главное вернуть в нужную вам коллекцию по итогу.

List<Customer__c> customers = [SELECT Account__c, Name FROM Customer__c];

Map<Id, List<Customer__c>> customersByAccountId = getAnyTypeByParentId(customers, 'Account__c');

System.debug(customersByAccountId);

public Map<Id, List<SObject>> getAnyTypeByParentId(List<sObject> sObjects, String fieldName) {
    Map<Id, List<SObject>> sObjectsMap = new Map<Id, List<SObject>>(); 
    for(sObject so : sObjects) {
        Id soId = (Id)so.get(fieldName);
        if(sObjectsMap.containsKey(soId)) {
            sObjectsMap.get(soId).add(so);
        } else {
            sObjectsMap.put(soId, new List<SObject>{so});
        }
    }

	return sObjectsMap;
}

По итогу, обе записи с типом Customer, сгруппированный по полю Account__c.
image
image

Что вывела консоль:

Map result
{
0012p00002IqLcnAAF = (Customer__c:{Account__c = 0012p00002IqLcnAAF, 
                                   Name = John Galt, 
                                   Id = a002p00000yhvSpAAI}), 
0012p00002fzddGAAQ = (Customer__c:{Account__c  =0012p00002fzddGAAQ, 
                                   Name = Ayn Rand, 
                                   Id = a002p00000yhvT4AAI})
}

Интересно одно, Map преобразовала коллекцию sObject уже при передаче параметров в метод, или во время возвращение Map из метода в надлежащий тип…
Як на вашу думку ?

2 Likes

image

Так а в чем проблема проверить?
Сделайте два дебага

System.debug(getAnyTypeByParentId(customers, 'Account__c'));

Map<Id, List<Customer__c>> customersByAccountId = getAnyTypeByParentId(customers, 'Account__c');
System.debug(customersByAccountId);